前言
本章将专门介绍与执行上下文创建阶段直接相关的最后一个细节——this是什么?以及它的指向到底是什么。
了解this
也许你在其他面向对象的编程语言曾经看过this
,也知道它会指向某个构造器(constructor)所建立的对象。但事实上在JavaScript里面,this
所代表的不仅仅是那个被建立的对象。
先来看看ECMAScript 标准规范对this 的定义:
「The this keyword evaluates to the value of the ThisBinding of the current execution context.」
「this 这个关键字代表的值为当前执行上下文的ThisBinding。」
然后再来看看MDN 对this 的定义:
「In most cases, the value of this is determined by how a function is called.」
「在大多数的情况下,this 其值取决于函数的调用方式。」
好,如果上面两行就看得懂的话那么就不用再往下看了,Congratulations!
… 我想应该不会,至少我光看这两行还是不懂。
先来看个例子吧:
var getGender = function() {
return people1.gender;
};
var people1 = {
gender: 'female',
getGender: getGender
};
var people2 = {
gender: 'male',
getGender: getGender
};
console.log(people1.getGender()); // female
console.log(people2.getGender()); // female
what?怎么people2变性了呢,这不是我想要的结果啊,为什么呢?
因为getGender()
返回(return)写死了people1.gender
的关系,结果自然是’female’。
那么,如果我们把getGender
稍改一下:
var getGender = function() {
return this.gender;
};
这个时候,你应该会分别得到female
与male
两种结果。
所以回到前面讲的重点,从这个例子可以看出,即便people1
与people2
的getGender
方法参照的都是同一个getGender function,但由于调用的对象不同,所以执行的结果也会不同。
现在我们知道了第一个重点,**this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数的调用方式。**如何的区分this呢?
this到底是谁
看完上面的例子,还是有点似懂非懂吧?那接下来我们来看看不同的调用方式对 this 值的影响。
情况一:全局对象&调用普通函数
在全局环境中,this 指向全局对象,在浏览器中,它就是 window 对象。下面的示例中,无论是否是在严格模式下,this 都是指向全局对象。
var x = 1
console.log(this.x) // 1
console.log(this.x === x) // true
console.log(this === window) // true
如果普通函数是在全局环境中被调用,在非严格模式下,普通函数中 this 也指向全局对象;如果是在严格模式下,this 将会是 undefined。E