为什么可以';我不能在javascript代码中继承动物类的原型吗?

为什么可以';我不能在javascript代码中继承动物类的原型吗?,javascript,Javascript,我正在尝试创建一个新类Dog,它通过原型继承从Animal类继承: function Animal() { this.name = "animal"; this.writeName = function() { document.write(this.name); } } function Dog() { this.name = "dog"; this.prototype = new Animal(); } new Dog().writeName() ​

我正在尝试创建一个新类
Dog
,它通过原型继承从
Animal
类继承:

function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  this.name = "dog";
  this.prototype = new Animal();
}

new Dog().writeName()

但是,我得到了一个Javascript错误:
uncaughttypeerror:Object没有方法“say”

为什么??
对象不应该保留一个
动物
对象作为原型吗?

原型属性只是一个常规属性。处理委托的真正[[Proto]]属性是隐藏的,在创建对象后不能直接操作(除了一些扩展:在Firefox中,它是
\uuuuuuuuuuuuu
属性)

一个精神上与您所做的类似的正确Javascript继承示例将使用Object.create创建具有正确[[Prototype]]属性的狗:

function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  var dog = Object.create(new Animal())
  dog.name = "dog";
  return dog;
}

(new Dog()).writeName()
一个更惯用的例子是ryan的答案,尽管我建议使用
Object.create
而不是
new Animal
来实例化狗的原型,我会将动物方法放在一个单独的动物原型中,而不是像您这样在构造函数中手动附加它们

function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  this.name = "dog";

}
Dog.prototype = new Animal();
dog = new Dog();
dog.writeName();
现在狗具备了动物的所有特性


@ryan的答案当然是正确的,但他并没有说这有什么不同,初学者可能不太清楚,所以

你犯的错误是
this.prototype=new Animal()
动物
实例分配给当前
实例(由
引用)上名为
原型
的属性,但在此上下文中名为
原型
的属性没有任何特殊之处


prototype
属性仅在函数对象上具有魔力。使用
new SomeFunc()
创建
SomeFunc
的新实例时,新对象的内部/隐藏[[prototype]]指针将引用
SomeFunc.prototype
指向的对象。
prototype
名称在任何其他上下文中都不特殊。

您确定粘贴了正确的代码吗?单词
say
一次都没有出现。因为没有类?;)但是问题是,
这个
在当时已经是错误的对象(以及[[prototype]]对于
新的
来说太晚了)。顺便说一句,使用console.log而不是document.write和alert。从长远来看,这会让你的生活变得更轻松。@pst:我刚才说的是他希望“原型”属性有什么特别的表现。好吧,那更好,+1:-)是
对象。创建(原型)
[本机]在第三版中提供,不过?@pst:我现在记不起来了,但是当它不可用时,为它编写一个polyfill是非常容易的:最近有人对此添加了一个答案,所以它出现在我的列表中,这是一种使用prototype和Object.create的奇怪方式。Animal有实例成员(即this.name),您可以通过调用
Animal.call(this,“dog”)来“继承”在Dog构造函数中。Animal具有共享成员(writeName),该成员应声明为
Animal.prototye.writeName=function()
,可由Dog通过
Dog.prototype=Object.create(Animal.prototype)继承
以避免每次创建Dog实例时完全覆盖Dog原型@HMR:这看起来很奇怪的原因是因为我使用
new
关键字调用我的构造函数,但我没有利用
.prototype
的魔力。这是为了使事情更接近原始问题,但我想可能更清楚的是,尽可能将函数重命名为
make_animal
make_dog
,并在不使用
new
关键字的情况下调用它们,因为这样很明显,我的代码实际上没有在任何地方使用
This