JavaScript 中的 this 的指向,完全取决于调用的方式.
调用
全局调用
1 | console.log(this); //全局对象,在浏览器中为 window 对象,在 nodejs 中为 global,方便起见,后面我们都是在浏览器中运行,即全局对象为 window |
直接作为函数调用
函数可以被直接调用,这时 this 指向全局对象.比如下面的例子:
1 | function f1(a1) { |
注意在全局模式中,函数的 this 为 undefined,因为严格模式禁止 this 关键字指向全局对象.因此:
1 | ; |
作为对象的方法调用
在 JavaScript 中,函数也是对象,因此函数也可以作为对象的一个属性,此时这个函数被称为这个对象的方法,在这个方法中使用的 this 指向当前的对象.
1 | var point = { |
对于内部函数,即声明在另外一个函数体内的函数,这种绑定到全局对象的方式会产生另外一个问题。我们仍然以前面提到的 point 对象为例,这次我们希望在 moveTo 方法内定义两个函数,分别将 x,y 坐标进行平移。结果可能出乎大家意料,不仅 point 对象没有移动,反而多出两个全局变量 x,y。
1 | var point = { |
这属于 JavaScript 的设计缺陷,正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,约定俗成,该变量一般被命名为 that。
1 | var point = { |
作为构造函数调用
构造函数的目的是构造对象,因此 this 的指向即为新构造的对象.
1 | ; |
但是需要注意的是,如果忘记加 new
的话 ,构造函数中的 this 仍然是指向 window 的(在严格模式中为 undefined)
1 | function F1() { |
作为 class 中调用
es5 中添加了 class 的概念,其实就是构造函数的语法糖,因此在 class 中 this 的指向与在构造函数中 this 的指向相同.
改变 this 的指向
箭头函数
箭头函数的 this 始终指向函数定义时的 this,而非执行时。,箭头函数需要记着这句话:“箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。
在函数内部使用 _this
先将调用这个函数的对象保存在变量 _this 中,然后在函数中都使用这个 _this,这样 _this 就不会改变了。
1 | var name = "windowsName"; |