持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
this 共有几种情况
判断 this,一定不要看在哪里定义。一定只看将来在哪里以及如何被调用。
obj.fun(),this指向.前的obj对象new构造函数,this指向new正在创建的新对象- 构造函数
.prototype.fun = function(){}- 因为将来原型对象中的方法,都是
子对象.fun()的方式调用。所以this指向将来调用这个fun函数的.前的某个子对象。
- 因为将来原型对象中的方法,都是
fun()(普通函数调用)、匿名函数自调用和回调函数中的this指向window。严格模式(usestrict)下,this指向undefined- DOM 事件处理函数里的
this指向当前正在触发事件的.前的 DOM元素对象button.onclick = function(){}button.addEventListener("click", function(){})- 注意:这里不能改成箭头函数,一旦改为箭头函数,
this就指向外层的window
- 箭头函数中的
this指向当前函数之外最近的作用域中的this- 几乎所有匿名函数都可用箭头函数简化
- 箭头函数是对大多数匿名函数的简写
箭头函数修改this
先来看下面这个例子:
var lilei = {
name: "Li Lei",
friends: ["laowang", "laizhang", "laoli"],
info: function() {
this.friends.forEach(function(item) {
console.log(`${this.name} 认识 ${item}`)
})
}
}
lilei.info()
这段程序的输出结果:
认识 laowang
认识 laizhang
认识 laoli
可以看到并没有打印出 this.name,这是因为 forEach 中是一个回调函数,回调函数的 this 是指向 window 的。
而 info 函数中的 this.friends 为什么可以拿到呢?
这是因为我们调用 info 函数的时候,是通过 lilei.info 调用的,此时 this 会指向 . 前面的对象。
那么我们现在来用箭头函数修改上述的代码:
var lilei = {
name: "Li Lei",
friends: ["laowang", "laizhang", "laoli"],
info: function() {
this.friends.forEach((item) => {
console.log(`${this.name} 认识 ${item}`)
})
}
}
lilei.info()
此时打印的结果为:
Li Lei 认识 laowang
Li Lei 认识 laizhang
Li Lei 认识 laoli
箭头函数其中的 this 会指向当前函数作用域之外最近的 this
那么,info 函数能改成箭头函数吗?
根据箭头函数 this 指向外层的原理,我们会发现函数中的 this.friends 相当于 window.friends 了,此时就会出错。
将普通函数修改为箭头函数的效果(bind)
var lilei = {
name: "Li Lei",
friends: ["laowang", "laizhang", "laoli"],
info: function() {
this.friends.forEach(
function(item) {
console.log(`${this.name} 认识 ${item}`)
}.bind(this)
)
}
}
lilei.info()
箭头函数底层相当于 .bind()
所以,call 无法替换箭头函数中的 this。因为 bind 是永久绑定的(不可替代)
call和apply是临时替换一次函数中的this
bind是永久替换函数中的this
什么情况下使用箭头函数
- 可以改为箭头函数的情况
- 如果函数中不包含
this - 希望函数内的
this与函数外的this保持一致
- 如果函数中不包含
- 不可改为箭头函数的情况
- 不希望函数内的
this与函数外的this保持一致 - js事件的处理函数不能改
- 不希望函数内的