为何无需绑定函数?ES6类方法this指向问题咨询
contains方法仍能访问到正确的this? 嗨,这个问题的核心在于JavaScript中this的绑定规则,咱们结合你的代码来一步步分析:
一、普通方法版本的contains为什么能拿到正确的this
先看你原本的Names类:
class Names { constructor (names) { this.names = names; } contains (names) { console.log(this); } }
在Hello组件的handleClick里,你是这样调用contains的:
handleClick = () => { this.namesInstance.contains(["Madrid"]); }
这里的关键是调用方式:你是通过this.namesInstance这个实例直接调用contains方法的(也就是实例.方法()的形式)。在JavaScript中,这种调用属于隐式绑定——当函数作为对象的方法被调用时,this会自动绑定到这个调用对象(也就是namesInstance这个Names类的实例)上。
你可能会疑惑为什么不需要手动绑定?其实手动绑定(比如在构造函数里this.contains = this.contains.bind(this))通常是在方法被单独传递的时候才需要,比如如果直接写onClick={this.namesInstance.contains},这时候contains会被当作独立函数执行,this就会丢失;但你现在是在箭头函数handleClick内部,通过实例去调用方法,所以this的绑定是自然生效的。
二、改成箭头函数版本的contains为什么也能拿到正确的this
如果把contains改成箭头函数:
class Names { constructor (names) { this.names = names; } contains = (names) => { console.log(this); } }
箭头函数的this规则和普通函数完全不同:箭头函数没有自己的this,它的this是定义时所在作用域的this。在类的实例属性中定义箭头函数时,这个箭头函数是在类的实例化过程中(构造函数执行阶段)创建的,此时作用域的this就是Names类的实例,所以箭头函数里的this会一直指向这个实例——不管你怎么调用它,this都不会变。
另外,类中的箭头函数是作为实例的自有属性存在的(而普通方法是在类的原型上),所以你在控制台输出this的时候,能看到实例上直接挂载了contains这个箭头函数,而普通方法版本的contains是在原型链上的。
总结一下:
- 普通方法通过
实例.方法()调用时,隐式绑定让this指向实例; - 箭头函数版本则是通过捕获定义时的
this,始终指向实例。
内容的提问来源于stack exchange,提问作者rmartrenado

