完全掌握this在JavaScript中的指向,吹散笼罩在this周围的重重迷雾,理解谁决定了this的指向,看完本篇你能在代码运行之前就可以判断出this的指向。
我们都曾以不同的方式在函数中看见过this,但仍然不能准确的指出this在JavaScript中指向谁,本篇将让你完全掌握this。
五大规则
(1) 如果 new 关键词出现在被调用函数的前面,那么JavaScript引擎会创建一个新的对象,被调用函数中的this指向的就是这个新创建的对象。
function ConstructorExample() {
console.log(this);
this.value = 10;
console.log(this);
}
new ConstructorExample();
// -> ConstructorExample {}
// -> ConstructorExample { value: 10 }
(2) 如果通过apply、call或者bind的方式触发函数,那么函数中的this指向传入函数的第一个参数。
function fn() {
console.log(this);
}
var obj = {
value: 5
};
var boundFn = fn.bind(obj);
boundFn(); // -> { value: 5 }
fn.call(obj); // -> { value: 5 }
fn.apply(obj); // -> { value: 5 }
(3) 如果一个函数是某个对象的方法,并且对象使用句点符号触发函数,那么this指向的就是该函数作为那个对象的属性的对象,也就是,this指向句点左边的对象。
var obj = {
value: 5,
printThis: function() {
console.log(this);
}
};
obj.printThis(); // -> { value: 5, printThis: ƒ }
(4) 如果一个函数作为FFI被调用,意味着这个函数不符合以上任意一种调用方式,this指向全局对象,在浏览器中,即是window。
function fn() {
console.log(this);
}
// If called in browser:
fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
注意,第4条规则和第3条很类似,不同的是当函数没有作为方法被调用时,它将隐式成为全局对象的属性——window。也就是当我们调用 fn(),可以理解为window.fn(),根据第三条规则,fn()函数中的this指向的就是window。
function fn() {
console.log(this);
}
// In browser:
console.log(fn === window.fn); // -> true
(5) 如果出现上面对条规则的累加情况,则优先级自1至4递减,this的指向按照优先级最高的规则判断。