一句话概括this指向问题(谈谈对this指向的理解)
一句话概括
js this指向问题是一个痛点,但理解也不难,核心思想:
this指向并不取决于定义,而是取决于调用
解释
在this定义的地方,沿着作用域向上找,找到最近的一个function(箭头函数除开,因为es6的箭头函数不带有this),看这个function最终是怎样执行的,this的指向就取决于所属function的调用方式,而不是定义。
function的调用一般分以下5种情况
作为函数调用
,即:fun()
this指向全局对象,注意严格模式问题(严格模式全局的this指向的是undefined)
在浏览器里全局对象是window,在node里全局对象是Object [global]作为方法调用
,即:obj.fun() / obj.bar.fun() / obj['fun']
this指向最终调用这个方法的对象作为构造函数调用
,即:new Foo()
this指向一个新对象foo {}function foo(){ console.log(this) // => foo {} } new foo() 复制代码
特殊调用
,即:fun.call() / fun.apply() / fun.bind()
this指向绑定的第一个参数成员,如果没有传入参数,则指向全局对象找不到所属的function,就是全局对象
掌握这5点总结,能覆盖所有的this指向问题,下面一些测试,你能答对吗?
测试
1、
var length = 10 function fn() { console.log(this.length) } const obj = { length: 5, method(fn) { fn() arguments[0]() } } obj.method(fn, 1, 2) 复制代码
浏览器里执行打印10 3
第一个10,this命中情况1:作为函数调用,this指向全局,所以访问挂载到window上的length为10
第二个3,this命中情况2:作为方法调用,this指向arguments对象{ '0': [Function: fn], '1': 1, '2': 2 },所以length打印3
2、
const obj1 = { foo(){ return () => { console.log(this) } } } obj1.foo()() const obj2 = { func : () => { console.log(this) } } obj2.func() 复制代码
第一个打印obj1对象,this命中情况2:作为方法调用,沿this往上找跳过箭头函数找到function foo,foo由obj1调用,则指向obj1
第二个浏览器打印window,this命中情况5:向上找不到function,就指向全局
3、
class Person{ say = () => { console.log(this) } } const p = new Person() p.say() 复制代码
打印实例Person,this命中情况3:作为构造函数调用,class是Function的语法糖,实质是function,this指向实例p
作者:熊猫爱吃笋
链接:https://juejin.cn/post/7029213661692428295