Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you help clarify Javascript prototype inheritance method invocation?

Tags:

javascript

In this block of code:

var Fruit = function() {}

Fruit.prototype = {
    color: function () {
        console.log('Fruit color...')
    }
}

var Apple = function () {}

Apple.prototype = new Fruit()
Apple.prototype.constructor = Apple

var a = new Apple()
Apple.prototype = null // the question!!!
a.color()

When Apple.prototype has been set to null, why can the instance a still invoke the color method?

like image 797
huang.xinghui Avatar asked Jul 07 '15 02:07

huang.xinghui


People also ask

Is JavaScript prototype inheritance?

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.

How does JavaScript prototype inheritance work?

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

What is prototype in JS inheritance example?

prototype , which is an object that sets properties and methods to all other JavaScript data types. Each type of prototype (for example array prototype) defines its own methods and properties, and in some cases overrides the Object. prototype methods and properties (that's why arrays have methods that objects don't).

What are prototype methods in JavaScript?

Prototypes are the mechanism by which JavaScript objects inherit features from one another. In this article, we explain what a prototype is, how prototype chains work, and how a prototype for an object can be set.


1 Answers

You're changing the Apple.prototype reference after you have created the instance a.

Changing the reference here doesn't change it for existing instances.

You'll also find

var a = new Apple();
Apple.prototype = {}; // some other object
a instanceof Apple; // false

i.e. because we've changed the inheritance chain of Apple a is no longer considered an Apple.

Setting Foo.prototype = null will cause a TypeError if you attempt to to an instanceof Foo check


Changing a property of an Object doesn't change the reference to that Object. e.g.

var foo = {},
    bar = foo;
foo.hello = 'world';
foo === bar; // true

Changing the Object itself does change the reference

foo = {hello: 'world'};
foo === bar; // false

Or written in a way more closely to how the prototype is referenced from an instance,

var Foo = {}, // pseudo constructor
    bar = {},
    baz = {};
var fizz = {}; // fizz will be our pseudo instance

Foo.bar = bar;          // pseudo prototype
fizz.inherit = foo.bar; // pseudo inheritance
Foo.bar = baz;          // pseudo new prototype
fizz.inherit === foo.bar; // false, instance inheritance points elsewhere

Current best practice for setting up an inheritance chain is not to use new, but to use Object.create

Apple.prototype = Object.create(Fruit.prototype);

If you need the Fruit constructor called on Apple instances, you would do

function Apple() {
    // this instanceof Apple
    Fruit.apply(this);
    // ...
}
like image 118
Paul S. Avatar answered Oct 02 '22 00:10

Paul S.