一、定义
this 是对函数执行环境对象的引用,在函数运行食绑定, 默认为全局对象,在浏览器为 window 对象,在 Node 中为 exports 对象。如果是以对象的方法调用,this 就会指向这个对象。
二、this 的默认值
在ES5中, 如果在全局中直接调用函数, 函数中的this 值默认指向 window 对象。匿名函数的执行环境具有全局性,即 this 值默认为 window 对象。
var foo = function () {
console.log(this);
}
foo(); // window
// 上面的调用相当于 foo.call(null)
#三、以对象的方法调用
当函数作为对象的方法被调用时,this 指向这个对象, 由于在 javascript 中数组也是对象,当数组用下标方式调用函数时,this 也会指向这个数组。
var length = 5;
var obj = {
foo: function (fn) {
console.log(this.length); // this => obj
fn(); // this => window
arguments[0](); // this => arguments
var bar = arguments[0];
bar(); // this => window
},
length: 10
}
var fn = function () {
console.log(this.length);
}
obj.foo(fn);
//10, 5, 1, 5
第一个输出为10 是因为 foo 函数中的 this 指向 obj 对象, foo是作为 obj 的方法调用的, 所以输出 obj 中的 length 的值。
第二个输出5是因为函数中的 this 不具备传递性,也就是说在 foo 中调用的函数并不会继承 foo 中的this 值,所以 fn 相当于是在全局环境中调用的,this 指向全局对象,length 的值输出全局中定义的 length 的值。
第三个输出1 , 函数中的 this 指向 arguments 对象,由于数组也是对象,当用下标方式调用数组中的函数时,this
就会指向数组。
第四个输出5, 和上一个不同的是, 将 arguments 中的函数赋值给一个对象后,再调用这个函数, this 的值发生了改变, 并指向了全局对象。
四、绑定执行环境
函数可以使用 call, apply, bind 方法改变或绑定执行环境,call 和 apply 方法的第一个参数都会成为函数的 this 的值,当第一个参数为 null 时,this 默认指向全局对象。 bind 方法可以绑定 this 值,绑定后不管以何种方式调用,this 的值不会改变。
var obj = {};
var foo = function () {
console.log(this);
}
foo(); // this => window
foo.call(obj); // this => obj
foo.bind(obj);
foo(); // this => obj
五、new 操作符
new 操作符会让一个构造函数创建一个实例对象,并将这个实例对象以 this 的形式返回。
var A = function () {
this.a = 1;
return new B();
}
var B = function () {
this.b = 2;
}
var newA = new A();
console.log(newA.a, newA.b); // undefined, 2
console.log(newA instanceof A); // false
console.log(newA instanceof B); // true
从上面的代码中可以看出,当构造函数返回一个对象时,new 出来的 this 指向这个返回的对象,构造函数中的 this 的属性都不会添加到 new 出来的对象。