JavaScript类中this关键字的必要性及相关绑定疑问解答
MDN文档指出:当静态方法或原型方法在未指定this值的情况下被调用(比如把方法赋值给变量后调用),方法内部的this值会变为undefined。
class Animal { speak() { return this; } static eat() { return this; } } const obj = new Animal(); obj.speak(); // 返回Animal对象 const speak = obj.speak; speak(); // 返回undefined Animal.eat() // 返回Animal类 const eat = Animal.eat; eat(); // 返回undefined
为何在JavaScript类中调用声明的方法时需要this关键字?
JavaScript类的普通方法默认挂载在类的原型上,静态方法挂载在类本身。this的核心作用是让方法能访问当前实例(普通方法场景)或类本身(静态方法场景)的属性与其他成员。比如要在speak方法里访问实例的name属性,必须用this.name来定位到当前实例的对应属性。另外,类内部默认启用严格模式,this不会自动绑定全局对象,必须通过this明确指向实例或类,才能正常访问关联的成员。将类的普通/静态方法引用保存到变量后,为何会丢失this的引用?
this的指向是调用时动态决定的,而非定义时固定。当用obj.speak()调用时,.运算符前面的obj会自动成为this的指向;但把obj.speak赋值给变量speak后,调用speak()就变成了普通函数调用,没有了.运算符提供的上下文。由于类内部是严格模式,这种无上下文的函数调用会让this变为undefined。静态方法的逻辑完全一致:Animal.eat()调用时this指向Animal类,赋值后调用丢失上下文,this就变成undefined。类中的speak()作为普通类方法,是否属于文中所说的原型方法?
是的。JavaScript类里不带static修饰的普通方法,默认会被添加到类的prototype对象上,实例通过原型链继承该方法,和传统写法Animal.prototype.speak = function() {}的效果完全相同,因此属于原型方法。在非严格模式的传统函数语法示例中,“方法调用自动绑定初始this值”对应的是哪一行代码?
对应的是obj.speak()这一行。当使用.运算符调用方法时,this会自动绑定到.前面的对象(此处为obj),这就是“方法调用自动绑定初始this值”的场景。
文档给出的对比示例(非严格模式下):
function Animal() { } Animal.prototype.speak = function () { return this; } Animal.eat = function () { return this; } const obj = new Animal(); const speak = obj.speak; speak(); // 非严格模式下返回全局对象 const eat = Animal.eat; eat(); // 非严格模式下返回全局对象
内容的提问来源于stack exchange,提问作者ritwick_ _D

