MDN 的文章“继承和原型链”,在“创建和修改原型链的不同方式”:“使用构造函数”下,给出了以下示例:
function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype.addVertex = function (v) {
this.vertices.push(v);
};
...
下面写着:
构造函数从很早的 JavaScript 就已经可用。因此,它非常快、非常标准、并且非常易于 JIT 优化。但是,也很难“正确执行”,因为以这种方式添加的方法默认是可枚举的,这与类语法或内置方法的行为方式不一致。如前所述,较长的继承链也容易出错。
~~~编辑:~~~
好吧,我明白这个示例与类等效的区别在于,在构造函数方法中,原型上的方法是可枚举的:
for (const prop in Graph.prototype) {
console.log(prop);
} // -> addVertex
如果我使用类语法重写它,它们就不是:
class GraphCls {
vertices = [];
edges = [];
addVertex (v) {
this.vertices.push(v);
}
}
for (const prop in GraphCls.prototype) {
console.log(prop);
} // -> nothing
但是原型上的方法可枚举与不可枚举有什么问题呢?为什么“不可枚举”是“正确的方式”。
为什么“不可枚举”是“正确的方式”?文章已经在同一句话中解释了:它“
与类语法或内置方法的行为方式不一致”。除此之外,没有充分的理由使方法不可枚举。我认为 MDN 作者将十年前的最佳实践称为“不当”有点大胆,并且该文章中还有其他值得怀疑的陈述。
原型上的方法可枚举与不可枚举有什么问题?没有,真的。正如您所演示的,只有当有人在实例上使用
for…in
循环时才重要,无论如何没人应该这样做。