箭头函数
this 绑定原则
在箭头函数中,this与封闭词法环境的this保持一致。
- 箭头函数的this指向创建该函数时所在的上层作用域
- 箭头函数的this的绑定与**定义的位置(编写的位置)**有关系
- 箭头函数的 this与调用的位置没关系
- 箭头函数的this在函数创建时绑定。
内置函数中的 this 绑定
DOM 事件中的 this 绑定
-
通过
onclick
绑定事件: 箭头函数与调用 环境无关,this
指向在创建时已经绑定。<div class="box">点击事件</div>
<script>
const box = document.querySelector(".box");
box.onclick = (e) => {
console.log(e);
console.log(this); // 指向 Window {window: Window, self: Window, document: document, name: '', location: Location, …}
};
</script> -
通过
addEventListener
绑定事件: 箭头函数与调用环境无关,this
指向在创建时已经绑定<div class="box">点击事件</div>
<script>
const box = document.querySelector(".box");
box.addEventListener("click", (e) => {
console.log(e);
console.log(this); // 指向 Window {window: Window, self: Window, document: document, name: '', location: Location, …}
});
box.addEventListener("click", (e) => {
console.log(e);
console.log(this); // 指向 Window {window: Window, self: Window, document: document, name: '', location: Location, …}
});
box.addEventListener("click", (e) => {
console.log(e);
console.log(this); // 指向 Window {window: Window, self: Window, document: document, name: '', location: Location, …}
});
</script>
setTimeout 中的 this 绑定
-
普通函数: 该函数独立调用,this 绑定到了全局执行上下文 window
setTimeout(function(){
console.log(this); // 该函数独立调用,this 绑定到了全局执行上下文 window
},200); -
箭头 函数: 该函数创建环境所在的上层作用域为全局,所以 this 指向为 window
setTimeout(() => {
console.log(this); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
}, 200);
JS 数组方法中的 this 绑定
-
普通函数: 箭头函数创建时的上层作用域为全局,所以 this 指向 window
const array = ["a", "b", "c"];
array.forEach((value, index, arr) => {
console.log(value, index, arr); // a 0 (3) ['a', 'b', 'c'] 循环遍历 arr 指向数组
console.log(this); // this 指向 window
}); -
构造函数: 虽然 forEach 内部有对回调函数修改 this 指向,但是箭头函数的 this 只与创建该函数时的上层作用域有关,上层作用域为全局,this 指向 window
const array = ["a", "b", "c"];
array.forEach((value, index, arr) => {
console.log(value, index, arr); // a 0 (3) ['a', 'b', 'c'] 循环遍历 arr 指向数组
console.log(this); // this 指向 window
},array);
this 面试常考问题
-
根据问题,输出结果--forEach 改变 this 指向
function foo (value){
console.log(value,this.name);
}
const obj = {
name:'柏拉文'
};
[1,2,3].forEach(foo,obj);
// 结果为:
// 1 '柏拉文'
// 2 '柏拉文'
// 3 '柏拉文' -
根据问题,输出结果,并改正--对象属性为函数,且函数里面嵌套函数
-
this 指向 window
const obj = {
data:[],
getData:function(){
setTimeout(function(){
this.data = [1,2,3]; // setTimeout 中的 callback 回调函数是 window 调用的,所以回调函数中的 this 指向 window , this.data === window.data
console.log(this,this.data); // window window.data = [1,2,3]
},100);
}
}
obj.getData(); -
更改 this 指向方案一: 将 this 赋值给另一个变量保存指向
const obj = {
data:[],
getData:function(){ // getData 函数被 obj 对象调用,所以 getData 函数中的 this 指向 obj
const that = this; // 将 this 赋值给 that , that 指向 obj
setTimeout(function(){
that.data = [1,2,3];
console.log(that,that.data);
},100);
}
}
obj.getData(); -
更改 this 指向方案二 将自身调用的函数通过 bind 绑定指向
const obj = {
data:[],
getData:function(){
setTimeout(function(){
this.data = [1,2,3];
console.log(this,this.data);
}.bind(this),100);
}
}
obj.getData(); -
更改 this 指向方案三 将自身调用的函数使用箭头函数
const obj = {
data:[],
getData:function(){
setTimeout(()=>{
this.data = [1,2,3];
console.log(this,this.data);
},100);
}
}
obj.getData();
-