JavaScript中class声明的prototype方法存储位置及与构造函数区别是什么
核心原因说明
你观察到的差异本质是属性可枚举性配置不同造成的,class确实是构造函数的语法糖,原型方法的存储位置没有变化,仍然是挂载在对应构造函数的prototype对象上。
具体差异点
- class语法定义的原型方法默认不可枚举
通过class块内部语法声明的原型方法,JS引擎会默认将其enumerable(可枚举)属性描述符设为false。而绝大多数环境的console.log打印对象时,默认只会展示可枚举属性,因此你会看到输出的Person.prototype看起来是空对象,实际上方法是真实存在的。
你可以用以下代码验证方法确实存在于原型上:
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getInfo() { console.log(`First Name: ${this.firstName} \nLast Name: ${this.lastName}`); } } // 直接访问方法是存在的 console.log(Person.prototype.getInfo); // 查看原型上的所有自有属性(包含不可枚举) console.log(Object.getOwnPropertyNames(Person.prototype)); // 输出 ['constructor', 'getInfo'] // 查看属性的可枚举配置 console.log(Object.getOwnPropertyDescriptor(Person.prototype, 'getInfo').enumerable); // 输出 false
- 手动赋值的原型方法默认可枚举
你用构造函数实现时,通过Person.prototype.getInfo = function() {}这种赋值方式新增的属性,默认enumerable为true,因此打印Person.prototype时可以直接看到该方法。
补充说明
这个差异是ES6设计class时的有意为之:原型上的公共方法默认不需要被遍历对象属性的操作(比如for...in)枚举出来,属于把社区长期的最佳实践做成了默认规范,class底层的原型链逻辑、实例调用逻辑和传统构造函数完全一致。
内容的提问来源于stack exchange,提问作者ansme
相关产品推荐
相关产品推荐

