为什么我的class级原型不工作?
为了构build我的JavaScript代码,我想使用类 ,ES6的原型inheritance的语法糖。 虽然我遇到了麻烦:看来我的原型方法没有按预期工作,这让我觉得我可能对JavaScript类有一个基本的误解,和/或它们是如何工作的。
采取下面的代码,它声明了一个传统的构造函数Cat
并修改了它的原型,还有一个ES6类的Dog
,里面定义了一个原型方法。
// Traditional Cat Constructor // =========================== function Cat(name) { this.name = name; this.sound = "Meow."; } Cat.prototype.speak = function() { console.log(this.sound || "I don't make a sound."); }; // Dog via ES6 Class // ================= class Dog { constructor(name) { this.name = name; this.sound = "Woof!"; } speak() { console.log(this.sound); } } var cat = new Cat("Bella"); var dog = new Dog("Sparky");
在NodeJS (用4.4.2和6.0.0-pre进行testing)中,当我尝试获取Dog
实例的原型时,我得到一个空对象,但是我仍然可以调用实例的原型方法。
Object.getPrototypeOf(cat); // -> Cat { speak: [Function] } Object.getPrototypeOf(dog); // -> Dog {} cat.speak(); // -> Meow. dog.speak(); // -> Woof!
在谷歌浏览器 ,我期望结果是相同的(自节点使用其引擎),我反而得到预期的结果:
Object.getPrototypeOf(cat); // -> Object {} // -> constructor: function Cat(name) // -> speak: function() // -> __proto__: Object Object.getPrototypeOf(dog); // -> Object {} // -> constructor: function(name) // -> speak: function() // -> __proto__: Object
我在Node中得到一个错误,说我在一个类中定义的原型方法不是他们类的实例的函数,这是我注意到这一点的唯一原因,但不幸的是现在看来我不能再现这个问题。
无论如何,上述不正确的,有没有解释为什么这个代码是这样的行为?
为什么我的class级原型不工作?
只是因为输出不是你所期望的,并不意味着它不工作。 节点REPL和console
都没有标准化。 实现是完全自由的输出任何他们想要的。
真正知道某个“有效”的唯一方法就是使用它。 所以尝试调用dog.speak()
。
无论如何,上述不正确的,有没有解释为什么这个代码是这样的行为?
类方法是不可枚举的属性,因此它们不会显示在Node输出中。 简单的例子:
> var foo = {}; undefined > Object.defineProperty(foo, 'bar', {value: 42, enumerable: false}); {} > console.log(foo); {} undefined > foo.bar 42 >
关于Chrome的输出,似乎你扩大了对象。 Chrome始终显示可枚举和不可枚举的属性。
> var foo = {}; undefined > Object.defineProperty(foo, 'bar', {value: 42, enumerable: false}); Object {bar: 42} > console.dir(foo); Object bar: 42 __proto__: Object undefined
Chrome浏览器似乎也在总结中显示了不可枚举的属性。 但是,尽pipeChrome和Node共享相同的引擎,但它们可能不共享console
或输出生成的相同逻辑。