Scope (1) - "这"是啥

白鹤亮翅

在 JavaScript 中,对象的方法访问自身内部的属性,看起来顺理成章:

> module = { x: 100, getX: function() { return this.x; } }
{ x: 100, getX: [Function: getX] }
> module.getX();
100

设全局变量的时候,x 和 this.x 也是互通的:

> x = 10
10
> this.x
10
> this.x = 1
1
> x
1

当场打脸

只要把这个方法提取出来赋给另一个变量,或者当作普通回调传递:

> getX2 = module.getX;
[Function: getX]

同样一个函数,执行结果却完全翻车:

> getX2();
1

见招拆招

getX2() 虽然和 module.getX() 指向同一个函数体,但普通函数内部的 this 并不由定义位置决定,而是取决于被调用的方式(谁在调用它):

  • 执行 module.getX() 时,调用者是 module,所以 this 指向该对象;
  • 执行 getX2() 时属于独立函数调用,其 this 指向全局对象(在非严格模式下是 global 或 window,严格模式下则是 undefined)。

为了锁死预期的作用域,可以使用 bind() 绑定宿主对象:

> getX3 = getX2.bind(module);
[Function: bound getX]
> getX3();
100

在现代前端开发中,也可以使用 ES6 箭头函数(lexical this)或者类字段方法来避免 this 丢失。

Loading...