admin管理员组

文章数量:1279242

I can create a Cat object and set a method on it's prototype to print out the cat's name.

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=".1.1/jquery.min.js"></script>
<div id="result"></div>

I can create a Cat object and set a method on it's prototype to print out the cat's name.

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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>

However, when I try to set the cat's prototype to an animal, I can't access the speak method:

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

Why does fluffy not get the speak() method of its prototype?

Share Improve this question asked Nov 29, 2014 at 23:35 BanksySanBanksySan 28.6k36 gold badges125 silver badges229 bronze badges 2
  • 2 If you want to learn how to do inheritance in JS, please read this guide . prototype is a property of the constructor function, not the instance. "Why does fluffy not get the speak() method of its prototype?" Because it's not on its prototype. You are never mutating Cat.prototype. – Felix Kling Commented Nov 29, 2014 at 23:37
  • Thanks @FelixKling, it was the scoping of the this that was missing. Quick read, problem solved. – BanksySan Commented Nov 29, 2014 at 23:41
Add a ment  | 

2 Answers 2

Reset to default 9

If you want to learn how to do inheritance in JS, please read this guide . prototype is a property of the constructor function, not the instance.

Why does fluffy not get the speak() method of its prototype?

Because it's not on its prototype. You are never mutating Cat.prototype. The way you set up Animal, you would have to call Animal inside Cat instead:

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

But if you want proper prototype inheritance, define speak on Animal.prototype and set up inheritance via 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);

The problem is that you set speak as a privileged method inside Animal constructor.

However, that constructor is never called for Cat instances.

Moreover, you can't use prototype property to modify internal [[prototipe]] and change the object from which properties should be inherited. You can use non standard __proto__ or ECMAScript6 Object.setProtetipeOf, but better don't do that.

Instead, better use this approach:

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

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();

本文标签: javascriptCan39t access methods on object39s prototypeStack Overflow