多种情况下的this指向规律
1.根据运行环境, 调用时的具体情况
window.bar = 2
var obj = {
foo: function () {
console.log(this.bar)
},
bar: 1
};
var foo = obj.foo; // 只是将函数体body赋给foo
obj.foo() // 1
foo() // 2
2.通过Function.prototype.bind | apply | call API改变this指向
window.x = 0;
function test() {
console.log(this.x);
}
var obj = {
x: 1,
m: test
};
obj.m() // 1
obj.m.apply(window) // 0
举个很常用的小例子 => 类数组转数组就可以用call()
[].slice.call(`传进你的类数组对象`).forEach()
slice内部实现代码
Array.prototype.slice = function(start,end){
var result = new Array();
start = start || 0;
end = end || this.length; // 此时this指向类数组对象, 类数组也有length
for(var i = start; i < end; i++){
result.push(this[i]); // 此时this指向类数组对象, 类数组也可以通过XXX.[i]的形式访问属性
}
return result;
}
3.箭头函数
// 1. winodw.setTimeout() => 只不过window可以被省略
window.x = 250
var obj = {
x:100, //属性x
show(){
setTimeout(function(){
console.log(this.x);
},500);
}
};
obj.show(); // 250
// 2. 箭头函数的this指向其定义环境中的对象, 而非调用时的对象
window.x = 250
var obj = {
x:100, //属性x
show(){
setTimeout(()=>{
console.log(this.x);
},500);
}
};
obj.show(); // 100
// PS: 请避免这种写法, this会指向window, 最好使用ES6的对象属性简写
// bad
show: () => {
console.log(this)
}
// good
show() {
console.log(this)
}
5.闭包函数中的this
window.x = 250
var obj = {
x: 100,
wrap(){
return function(){
return console.log(this.x)
}
}
};
obj.wrap()() // 250
let aa = obj.wrap()
aa() // 250
个人理解 => 闭包函数由于没有被调用, 故总是指向全局window