版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
如何判断this指向问题?记住一句话即可:谁调用它,this就指向谁。
先看几个调用场景:
function foo() {
console.log(this.a)
}
var a = 1
foo()
const obj = {
a: 2,
foo: foo
}
obj.foo()
const c = new foo()
分析如下:
foo来说,不管foo函数被放在了什么地方,this一定是window;obj.foo()来说,我们只需要记住,谁调用了函数,谁就是this,所以在这个场景下foo函数中的this就是obj对象;new的方式来说,this被永远绑定在了c上面,不会被任何方式改变this。箭头函数this:
箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于自己的this,它所谓的this是捕获其所在上下文的this值,作为自己的this值,并且由于没有属于自己的this,箭头函数是不会被new调用的,这个所谓的this也不会被改变, 我们可以用Babel理解⼀下箭头函数:
// ES6
const obj = {
getArrow() {
return () => {
console.log(this === obj);
};
}
};
转化后
// ES5,由 Babel 转译
var obj = {
getArrow: function getArrow() {
var _this = this;
return function() {
console.log(_this === obj);
};
}
};
扩展:
最后种情况也就是bind这些改变上下文的API了,对于这些函数来说,this取决于第一个参数,如果第一个参数为空,那么就是window。
说到bind,不知道大家是否考虑过,如果对一个函数进行多次bind,那么上下文会是什么呢?
let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)() // => ?
如果你认为输出结果是a,那么你就错了,其实我们可以把上述代码转换成另一种形式:
// fn.bind().bind(a) 等于
let fn2 = function fn1() {
return function() {
return fn.apply()
}.apply(a)
}
fn2()
可以从上述代码中发现,不管我们给函数bind几次,fn中的this永远由第一次bind决定,所以结果永远是window。
思考:不同规则下的this最终指向哪里呢?
首先,new的方式优先级最高,接下来是bind这些函数,然后是obj.foo()这种调用方式,最后是foo这种调用方式,同时,箭头函数的this一旦被绑定,就不会再被任何方式所改变。
图解如下:(针对单个规则)
