JavaScript核心概念精讲
一个刚学 JavaScript 的同事拿着代码来找我,说他被 this 指向搞晕了。他写了这样一个函数:const user = { name: 张三, greet: function() { console.log(Hello, + this.name); } }; 单独调用 user.greet() 输出正常,但把方法赋值给一个变量再调用,this 就变成 undefined 了。他说:JavaScript 是不是有 bug?
JavaScript 没有 bug,是它的设计比你想象的灵活,而灵活性也带来了容易混淆的地方。下面这几个核心概念,搞懂了就能从根本上理解 JavaScript。
JavaScript 核心概念精讲:
概念一:作用域和闭包。 JavaScript 的作用域是函数级别的。变量在哪里定义,就在哪里可访问。函数内部可以访问外部的变量,反过来不行。闭包就是:一个函数记住了它创建时的作用域,即使这个作用域已经执行完了。比如一个计数器函数:外层函数定义一个 count 变量,内层函数返回 count++。每次调用内层函数,count 都会增加,因为内层函数一直保持着对外层 count 的引用。同事理解闭包后,发现之前看不懂的很多开源代码一下就能看懂了。
概念二:this 指向取决于调用方式,而不是定义位置。 这是 JavaScript 新手最困惑的地方。记住四句话:普通函数调用,this 指向全局对象(浏览器是 window);对象方法调用,this 指向该对象;箭头函数没有自己的 this,它的 this 继承自外层作用域;call、apply、bind 可以手动指定 this。同事用箭头函数重写了 greet 方法后,this 正确指向了 user 对象。箭头函数在这里解决了他最头疼的问题。
概念三:原型链和继承。 JavaScript 的继承和其他语言不一样。它不是类继承,而是原型链继承。每个对象都有一个内部属性指向它的原型,当访问一个属性时,如果对象本身没有,就会沿着原型链往上找。ES6 的 class 语法让这个过程看起来像传统面向对象,但底层仍然是原型链。不用怕原型链,记住一句话:原型链就是对象之间的关联,通过 proto 连接起来的链条。
概念四:事件循环和异步编程。 JavaScript 是单线程语言,但通过事件循环实现了非阻塞。过程很简单:同步代码直接执行,异步操作交给 Web API 处理,回调函数放到任务队列,主线程空闲后从队列取任务执行。Promise 和 async/await 是更优雅的异步处理方式。同事学会了 async/await 后说:原来异步代码也可以写得像同步代码一样清晰。

同事花了两周搞懂这四大概念后,再看 JavaScript 代码感觉完全不一样了。他说:以前写 JavaScript 像是在黑盒子里摸索,碰对了就运行,碰错了就报错。理解了核心概念之后,每个行为都有了合理的解释。编程语言的学习,归根结底是概念模型的理解。
推荐阅读:兴趣岛课程