如何使用prototype避免在javascript中复制函数?

如何使用prototype避免在javascript中复制函数?,javascript,Javascript,我编写这段代码是为了模拟OOP继承和在javascript中调用基类,它可以工作: function Animal(name,age) { this._name = name; this.setName = function (name) { this._name = name } this.getName = function() { return this._name } } function Cat(name,age) { Animal.

我编写这段代码是为了模拟OOP继承和在javascript中调用基类,它可以工作:

function Animal(name,age)
  {
    this._name = name; 
    this.setName = function (name) { this._name = name }
    this.getName = function() { return this._name }
  }

  function Cat(name,age)
  {
    Animal.call(this,name,age); // call baseclass constructor
    this.getName = function() { return Cat.prototype.getName.call(this)+", a cat" }
  }
  Cat.prototype = new Animal(); // will create the baseclass structure

  /// *****  actual execution  *****
  var puss = new Cat("Puss",3);
  var cheshire = new Cat("Cheshire",10);
  // do some actions
  console.log ( puss.getName() );
  // change cat's name
  puss.setName("Puss in boots");
  alert ( "new name -->"+puss.getName() );
问题是,对于“new Cat()”的每个实例,“getName”和“setName”函数都被复制。 我读过很多关于原型设计的文章,但没有一篇涉及调用基类函数的问题。

Javascript没有任何类型的“super”属性,这将 指向它的父类。而是使用 函数对象,它允许您使用不同的 对象作为其上下文。如果需要将参数传递给此 功能,它们将遵循“this”

在您的情况下,它对函数的作用与“方法”相同,因此您可以执行以下操作:

Animal.prototype.setName.call(this, name);

您正在寻找存储原型数据的
\uuuuuuuuuuuuuuuuuuuuu


如果你做一个
console.log(puss.\uu proto\uuuu.getName)
你会得到一个看起来像是“基类”的函数,但我不确定这是如何跨浏览器的。

你应该把方法分配给函数的原型,例如

function Animal(name, age) {
    this._name = name;
    this._age = age;
}
Animal.prototype.getName = function () { return this._name; }
Animal.prototype.setName = function (value) { this._name = value; }

function Cat(name, age) {
    Animal.call(this, name, age);
}
Cat.prototype = new Animal();
Cat.prototype.getName = function () { 
    return Animal.prototype.getName.call(this) + ", a cat"; 
}

这就是JavaScript的工作原理!每个新创建的对象都具有从原型复制的所有属性。这是正常行为,不是问题。你到底想要什么?给出TypeError:Animal.prototype.getName是未定义的抱歉,我在发布后对其进行了轻微更改。问题的一部分在于您在Animal函数中定义的setName和getName方法。这些也需要是原型。我鼓励您查看我提供的链接,因为他涵盖了所有这些内容。
\uuuuu proto\uuuu
在所有浏览器中都不可访问,应该避免。@FelixKling:直到/除非。。。“添加了第B.3.1节,其中指定了
\uuuuu proto\uuuuuu
功能。”有没有简单的方法可以防止动物的“构造器”运行两次?我不明白你的意思。怎么跑了两次?@NirO。是的,有。在ES5中,您可以使用(在不支持它的浏览器中,您可以使用链接中编写的垫片)。因此您将有:
Cat.prototype=Object.create(Animal.prototype)@chuckj第一次是Cat.prototype=新动物();第二个:var c=新猫(“puss”,1)@正如ZER0所指出的,通过使用
Object.create()
或它的一些多边形填充(参见ZER0的链接),您可以避免
newanimal()
。您只需要一个与
Animal()
创建的实例具有相同原型的对象。