江湖人称,谁调用 this,this 就指向谁。
那么 this 到底绑定或者引用的是哪个对象环境呢,以下便是四种规则
1. 默认绑定全局变量
function fn() { console.log(this.a); } var a = 2; fn(); // 2 | this 为默认的 window
2. 隐式绑定
function fn() { console.log(this.a); } var obj = { a: 2, obj2: obj2, } var obj2 = { a: 42, fn: fn, } obj.obj2.fn(); // 42 | this 引用上下文对象
但,特别注意一点,对象的存储问题,变量只是它的指针而已,而赋值改变的是数据
function fn() { console.log(this.a); } var obj = { a: 2, fn: fn, } var fn2 = obj.fn; fn2(); // undefined | this 此时是 window
3. 显式绑定
function fn() { console.log(this.a); } var obj = { a: 2, } fn.call(obj); // 2 | 将上下文赋给 fn
4. new 对象绑定
function Fn(a) { this.a = a; } var obj = new Fn(2); console.log(obj.a); // 2 | this 绑定在 Fn 上
关于 this 的难点和误区主要有两方面,this 的引用者,与,this 的作用域
function fn(i) { console.log('fn:', i); // 2 this.count++; // 此处的 this 指向 window,而不是下面的 fn.count } fn.count = 0; for(var i=0; i<3; i++) { if (i>1) fn(i); } console.log(fn.count); // 0 | fn.count 和 fn 没有半毛钱关系 console.log(count); // NaN | 首先 window.count 为 undefined,所以再加就是 NaN
function fn1() { var a = 2; this.fn2(); } function fn2() { console.log(this.a); // undefined // 此时的 this 依然指向 window,而不是由 fn1 传递上下文 } fn1();