Object.keys(Class.prototype) 与 Object.keys(Proto.prototype) 不同。为什么?

问题描述 投票:0回答:1

我正在阅读 ES6 课程,据说它只是语法糖。那为什么在

Object.keys
上调用
Class.prototype
没有列出类的方法呢?

class Class { whoami() { return "class"; } }

function Proto() {}
Proto.prototype.whoami = function () { return "proto"; }

console.log(Class.prototype); // { constructor: f() {}, whoami: f() {} }
console.log(Proto.prototype); // { constructor: f() {}, whoami: f() {} }

console.log(Object.keys(Class.prototype)); // []              <--- WHY ???
console.log(Object.keys(Proto.prototype)); // ["whoami"]
javascript es6-class
1个回答
0
投票

您观察到的

Object.keys(Class.prototype)
Object.keys(Proto.prototype)
之间的差异与类方法在 ES6 类中的定义和存储方式(与传统的基于原型的对象相比)有关。

在您的示例中,

Class
是一个 ES6 类,Proto 是具有手动定义原型的传统构造函数。

当您使用速记语法(如

whoami() { return "class"; }
)在 ES6 类中定义方法时,该方法将添加到类原型中。但是,默认情况下这些方法是不可枚举的,这意味着当您使用
Object.keys()
迭代对象的属性时,它们不会显示。

这是为了模仿其他编程语言(如 Java)中类方法的行为而做出的设计选择。在大多数情况下,您不希望这些内部方法在迭代对象的键时可见。

如果您想让方法可枚举(因此出现在

Object.keys(Class.prototype)
中),您可以显式地将方法的属性
descriptor
设置为可枚举

当您在构造函数的原型上手动定义方法(如

Proto.prototype.whoami = function () { return "proto"; }
)时,该方法将添加到原型中,且
enumerable
属性默认设置为 true。这就是为什么您会看到
Object.keys(Proto.prototype)
中的方法。

© www.soinside.com 2019 - 2024. All rights reserved.