深入理解this的指向问题(6种全)
一、this的指向主要有下面几种:
1、this出现在全局函数中,永远指向window
var Car = function() {
console.log(this); // window
console.log(this.Car==window.Car,Car==window.Car); // true true
}
Car();
Car作为全局函数,直接调用时,函数的this指向window。
也就是Car==window.Car===this.Car
2、this出现在严格模式中 永远不会指向window
函数中使用es5的严格模式‘use strict’,this为undefined
var Car = function() {
'use strict'
console.log(this); // undefined
}
Car();
3、当某个函数为对象的一个属性时,在这个函数内部this指向这个对象
如下图:在car这个对象的run方法中打印this为car本身。
var car = {
name:'丰田',
run() {
console.log(this); // {name: "丰田", run: ƒ}
}
}
4、this出现在构造函数中,指向构造函数新创建的对象
var Car = function(name) {
this.name = name;
console.log(this); // Car {name: "亚洲龙"}
// Car {name: "汉兰达"}
}
var myCar_1 = new Car('亚洲龙');
var myCar_2 = new Car('汉兰达');
上述代码中构造了两个实例对象myCar_1和myCar_2,构造函数里面的this分别指向创建的实例化对象myCar_1和myCar_2。
5、当一个元素被绑定事件处理函数时,this指向被点击的这个元素
var btn = document.querySelector('button');
btn.onclick = function() {
console.log(this); // <button>this</button>
}
6、this出现在箭头函数中时,this和父级作用域的this指向相同
接下来看一段比较复杂的代码:
const obj = {
Car() {
setTimeout(function() {
setTimeout(function() {
console.log(this); // window
})
setTimeout(()=>{
console.log(this); // window
})
})
setTimeout(() => {
setTimeout(function() {
console.log(this); // window
})
setTimeout(()=>{
console.log(this); // obj
})
})
}
}
obj.Car();
看到上述代码是不是有点懵逼。别急 ! ! !,
首先遇到function(){}这种格式,如果是直接调用,浏览器会把Core传进去,所以①和③this指向为window。
而箭头函数的this是指向父级作用域,➁的父级作用域是setTimeout(function(){})里面,
前面已经说过function(){}这种格式如果直接调用Core传进去,this指向为window,
所以➁的this指向=父级作用域的this指向=window,至于④就比较简单了,这里不做赘述。
二、修改this的指向
上文说了this在函数中的指向问题,那么如何修改this的指向呢?
1、使用call、apply、bind修改this指向
3、使用new关键字改变this指向
也就是上述第一大点的第三小点所举的例子。