无法访问对象原型的方法

时间:2014-11-29 23:35:07

标签: javascript

我可以创建一个Cat对象并在其原型上设置一个方法来打印出猫的名字。

var log = function(message) {
  var results = $('#result');
  results.append('<p>' + message + '</p>');
};

function Cat(name) {
  this.name = name;
}

Cat.prototype.speak = function() {
  log('My name is ' + this.name);
};

var fluffy = new Cat('Fluffy');
var tiddles = new Cat('Tiddles');

log(fluffy.name);
fluffy.speak();
log(tiddles.name);
tiddles.speak();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>

但是,当我尝试将猫的原型设置为动物时,我无法访问speak方法:

function Animal(name, sound) {
    this.name = name;
    this.sound = sound;

    this.speak = function() {
        log(sound + '! My name is ' + name);
    };
}

function Cat(name) {
    this.prototype = new Animal(name, 'Meow');
}

var fluffy = new Cat('Fluffy');

fluffy.speak();  // TypeError: undefined is not a function

为什么fluffy没有得到原型的speak()方法?

2 个答案:

答案 0 :(得分:7)

如果你想学习如何在JS中进行继承,please read this guideprototype构造函数的属性,而不是实例

  

为什么fluffy没有得到原型的speak()方法?

因为它不在原型上。你永远不会改变Cat.prototype。您设置Animal的方式,您必须在Animal内调用Cat

function Cat(name) {
    Animal.call(this, name, 'Meow');
}

但是如果你想要正确的原型继承,请在speak上定义Animal.prototype并通过Object.create设置继承:

function Animal(name, sound) {
    this.name = name;
    this.sound = sound;
}

Animal.prototype.speak = function() {
    log(this.sound + '! My name is ' + this.name);
};

function Cat(name) {
    Animal.call(this, name, 'Meow');
}
Cat.prototype = Object.create(Animal.prototype);

答案 1 :(得分:1)

问题是您在speak构造函数中将Animal设置为特权方法。

但是,永远不会为Cat个实例调用该构造函数。

此外,您不能使用prototype属性来修改内部[[prototipe]]并更改应继承属性的对象。您可以使用非标准__proto__或ECMAScript6 Object.setProtetipeOf,但最好不要这样做。

相反,更好地使用这种方法:

function SuperClass(args) {
    // Here add SuperClass privileged properties
}

// Here add public properties to SuperClass.prototype

function SubClass(otherArgs) {
    // Add SuperClass privileged properties to SubClass instances:
    SuperClass.call(this, args);

    // Here add SubClass privileged properties
}

// Make SubClass instances inherit from SuperClass.prototype:
SubClass.prototype = Object.create(SuperClass.prototype);

// Fix constructor property, overriden in the line above
SubClass.prototype.constructor = SubClass;

// Here add public properties to SubClass.prototype

&#13;
&#13;
function log(message) {
  document.body.innerHTML += '<p>' + message + '</p>';
}

function Animal(name, sound) {
  this.name = name;
  this.sound = sound;
}

Animal.prototype.speak = function() {
  log(this.sound + '! My name is ' + this.name);
};

function Cat(name) {
  Animal.call(this, name, 'Meow');
}

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

var fluffy = new Cat('Fluffy');

fluffy.speak();
&#13;
&#13;
&#13;