持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
前言
javascript中关键字this会在执行上下文中绑定一个对象,并且在不同的执行条件下会绑定不同的对象,简单理解,就是在不同的作用域下使用this调用,this的指向是不同的。
this指向window
什么是全局作用域?比如直接写在script标签中的js中的代码,就是全局作用域。 我们在script下写一个函数打印看看
function foo(){
console.log(this)
}
foo()
浏览器会打印
可以知道全局作用域下使用this ,就是指向window。但好像这样说不够通透,这this不是在函数里打印的吗。好像也是,我们基本也不会在全局作用域下直接使用this,都是在函数里调用。
我们这里其实是在全局作用域下调用了函数。所有的函数在被调用时,都会创建一个执行上下文:
- 这个上下文中记录着函数的调用栈、函数的调用方式、传入的参数信息等;
- this也是其中的一个属性;
这里可以看出,this是在函数调用时被绑定的一个对象,这里就是一个普通函数的调用,this默认绑定到了window对象上。
this指向某对象
另外一种情况就是this指向到了具体的某对象,这种情况就是函数是通过某个对象来调用的,或者说它时某个对象的内部函数。
const shy={
name:'the shy',
say:function(){
console.log(this);
},
foo:foo
}
shy.say()
我们在这个对象里,定义了一个say方法,然后通过对象.函数
方式来调用,那么这个this就是指向shy对象。
同样的如果我们在对象里在嵌套了一层对象,然后调用内部对象的这个函数,那么这个函数打印的this其实就是这个内部对象,可以看到跟函数实际调用的上层作用域有关。
const shy={
name:'the shy',
say:function(){
console.log(this);
},
foo:foo
}
const ning = {
name:'the ning',
shy:shy
}
ning.shy.foo()
const newNing = shy.foo
newNing()
//Window {window: Window, self: Window, document: document, name: '', location: Location, …}
这里我们把某个函数赋值给某个变量,然后通过这个变量去调用,那么这时候其实是window对象,因为实际函数调用地方并没有形成具体的绑定,所以默认是window。
箭头函数中的this
首先应该知道箭头函数是不会绑定this对象的,所以箭头函数里的this会从上层作用域去寻找,如setTimeout函数,我们先看如果不是箭头函数,情况是什么
const shy={
name:'the shy',
say:function(){
console.log(this);
setTimeout(function() {
console.log('setTimeout-',this);
}, 500);
},
foo:foo
}
可以看到如果setTimeout函数里,传入的是function函数写法,那么这里面的this就是全局的window对象。因为setTimeout其实就是挂载在window对象上,所以这里this是window。
如果我们把它改成箭头函数,那么结果就是
可以看到就是指向了它的上层作用域,就是shy对象。
总结
this指向问题也是一个小难点,要自己认真去思考理解,对每个调用处的this一步步分析,得出结论。