this指向谁?(基本指向原则)
- 真传一句话,假传万卷书。我们先说结论,在标准函数中this是把函数当成方法调用的上下文对象。(注意这里是标准函数中,与之对应的是箭头函数,下面会讲到)
- 概而言之,即为,谁调用函数,this就指向谁
- 当调用方法没有明确对象的时候,this指向全局对象window(严格模式下是undefined)
let user = {
firstName: "John",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
firstName = "spicyLemon"
user.sayHi();
复制代码
结果是什么?
显而易见是Hello,John。
因为这里是user调用的sayHi函数,所以this指向的自然就是user。这和我上面说的结论是一致的。
总结:this的指向是在调用时决定的,和书写的位置没有关系,这一点和闭包还有箭头函数刚刚好时相反的。(大多数情况下)
小测验
这里是一个小测验,如果你真正理解了上面的内容,那么应该不难。
var me = {
name: 'xiuyan',
hello: function() {
console.log(`你好,我是${this.name}`)
}
}
var you = {
name: 'xiaoming',
hello: function() {
var targetFunc = me.hello
targetFunc()
}
}
var name = 'BigBear'
you.hello()
复制代码
先思考一下再看答案。
如果你对了,那么恭喜你已经掌握this的基本指向规则了(也许)。如果你错了,那么请再仔细揣摩上面的内容。
答案是:BigBear
特殊情况下的this指向
setTimeout
这是第一例的变体
let user = {
firstName: "John",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
firstName = "spicyLemon"
setTimeout(user.sayHi, 1000);
复制代码
看完了么,来吧,说输出。
Hello,spicyLemon
这个时候肯定有人有疑惑了。
啊,博主你刚刚不是说谁调用的函数this就归谁么,这里确实是user来调用的啊。
- 确实这里写的是user.sayHi,我们的this此时应该指向user才对。
- 但是当将对象方法作为回调进行传递,例如传给setTimeout的时候,我们的this就不会像我们刚刚所想的那样指向user了
那是因为,这些回调都是在全局作用域下实现的。
无论是 setTimeout 还是 setInterval 里传入的函数,都会首先被交付到全局对象手上。
我们可以理解为,函数直接被整个交给了setTimeout,然后由setTimeout来调用
这时就不是user来调用了
因此,函数中 this 的值,会被自动指向 window。
setInterval
这里和setTimeout是一样的,我就不再多做赘述了。
立即执行函数(IIFE)
由于我们这一篇博客讲的是this指向,我就不再IIFE上多做赘述,这里直接上代码。
不了解的同学可以查看一下资料再回来看代码,我的IIFE是在红宝书(第四版)的314页看的,有书的同学可以直接翻看。
var name = 'spicyLemon'
var me = {
name: 'xiuyan',
sayHello: function() {
console.log(`你好,我是${this.name}`)
},
hello: function() {
(function(cb) {
cb()
})(this.sayHello)
}
}
me.hello()
复制代码
来吧,展示你们的输出相信经过这几分钟的锤炼你已经很难再错了。
答案是:你好,我是spicyLemon
特殊情况的总结
不管怎么样,这三个所谓的特殊情况里的this判断,还是离不开我开头说的this指向原则
多数情况下(99%)这三种情况的this都指向window
箭头函数
真传一句话,假传万卷书。我们直接说结论:箭头函数它没有自己的this,它的this是别人的,是定义它的对象的this。(这里不太严谨,但是比较好理解)
看代码
var name = 'BigBear'
var me = {
name: 'xiuyan',
hello: () => {
console.log(this.name)
}
}
me.hello()
复制代码
答案是spicyLemon
箭头函数比较特殊,这里我来一步一步引导大家
- 箭头函数它没有自己的this,它的this是别人的,是定义它的对象的this。这是我给的结论。
- 那么我们把它放在这个代码中来看,定义它的对象是user,user的this就是window了。
于是答案就解释的通了
箭头函数中的 this 比较特别,它和严格模式、非严格模式啥的都没关系。它和闭包很相似,都是 认“死理”——
认“词法作用域”的家伙。所以说箭头函数中的 this,和你如何调用它无关,由你书写它的位置决定(和咱们普通函数的 this规则恰恰相反~)
箭头函数正是由于没有自己的this所以它可以在那些没有自己的“上下文”,但在当前上下文中起作用的短代码的使用场景中大放异彩。
如有错误,请在评论区指正,看到后会修改。不明白的可以私信问我(虽然我也不是特别明白哈哈哈)