JavaScript类内部方法互调为何必须显式使用this关键字
JavaScript 类内方法互调要求显式写
this的核心原因 这个规则本质是JavaScript底层设计逻辑决定的,和Java、C++这类从诞生起就基于静态类模型实现面向对象的语言有根本区别:
- 词法作用域规则优先级更高,不存在自动的类成员兜底查找
JavaScript的作用域查找是纯词法层面的:执行函数时,引擎只会从当前函数局部作用域开始,逐层向外查找普通变量/函数,直到全局作用域,全程不会自动去当前实例的属性集合里做兜底匹配。如果在类方法里直接写testMethod1()而不加this.,引擎只会把它当成普通函数调用,找不到就直接抛引用错误,根本不会默认关联到当前实例的方法。
而Java、C++是编译型语言,编译器处理类成员函数时,会自动把未显式绑定的标识符优先匹配当前类的成员,相当于隐式补全了this.前缀,这个查找逻辑是编译阶段就完成的静态绑定,JavaScript没有这类编译期的类结构校验步骤,自然做不到这个隐式处理。 - JavaScript的
this是动态绑定的,方法和实例没有强绑定关系
ES6的class本质是原型继承的语法糖,类里定义的方法本质还是普通函数,可以被任意赋值、拆出来单独传递,脱离实例运行,这时候根本不存在“当前类实例”的概念,引擎不可能在方法定义阶段就把方法和固定实例绑定死。举个很简单的反例:
而Java、C++里的非静态成员方法不能脱离实例单独存在,方法和实例的绑定是强关联的,编译器自然可以安全地隐式注入class Test{ testMethod1() { console.log('hello world'); } testMethod2() { this.testMethod1(); } } let t = new Test(); // 把方法拆出来单独执行 const methodRef = t.testMethod2; methodRef(); // 严格模式下直接报错,因为此时this指向undefined,根本找不到testMethod1this引用。 class语法没有改变原型模型的本质
你写的类代码,翻译成ES5的原型写法逻辑完全等价:
所有类方法都是挂在构造函数function Test() {} Test.prototype.testMethod1 = function() { console.log('hello world'); } Test.prototype.testMethod2 = function() { this.testMethod1(); } let t = new Test(); t.testMethod1(); t.testMethod2();prototype属性上的独立函数,和生成的实例是分离的,只有通过实例调用方法时,才会动态把this绑定到对应实例上,这种设计下根本不可能实现“不写this自动匹配实例方法”的逻辑。
总结下来就是:Java、C++的类是编译期就确定结构的静态模板,成员和实例强绑定,编译器有足够信息帮你隐式补全
this;而JavaScript的类是原型机制的语法包装,方法是可独立传递的普通函数,this动态绑定,词法作用域又不会自动遍历实例属性,所以必须显式写this明确告诉引擎你要访问的是当前实例上的成员。
内容的提问来源于stack exchange,提问作者Machi
相关产品推荐
相关产品推荐

