Question

I've been learning prototypical inheritance in JavaScript from John Resig's Secrets of the JavaScript Ninja, and I was wondering what happens in the following code example (that I just made up).

function Person() {}

Person.prototype.sayHello = function() {
    alert("Hello World");
}

function Ninja() {}

Ninja.prototype.swingSword = function() {
    alert("I can swing my sword.");
}

Ninja.prototype = new Person();

var ninja1 = new Ninja();

As far as I know, the result of all of these lines of code is that the variable ninja1 references a Ninja object, that through its prototype, has the swingSword method, and through prototypical inheritance of Person's prototype, has the sayHello method.

Where I am confused is in the following: since the property swingSword (which happens to be a method) was attached to Ninja's prototype before a person instance was assigned to Ninja's prototype, wouldn't the swingSword property/method be overwritten by the later assignment of the Person instance? If not, how can Ninja's prototype property, which references the prototype object, reference both the Person instance, and have a swingSword property?

Was it helpful?

Solution

[...] that through its prototype, has the swingSword method, [...]

While the rest of that statement is correct -- that ninja1 references Ninja (well, technically, Ninja.prototype) and will have a sayHello through inheritance -- your later thoughts are correct regarding swingSword.

wouldn't the swingSword property/method be overwritten by the later assignment of the Person instance?

At the end of your snippet, ninja1.swingSword should be undefined.

console.log(typeof ninja1.swingSword); // 'undefined'

// as is:
console.log(typeof Ninja.prototype.swingSword); // 'undefined'

After Ninja.prototype = ..., the original prototype object that swingSword was attached to is no longer being referenced. So, it won't be used when creating new instances.


If you intend to set a new prototype object, you'll want make sure that's done before modifying it.

Ninja.prototype = new Person();

Ninja.prototype.swingSword = function() {
    alert("I can swing my sword.");
}

var ninja1 = new Ninja();

console.log(typeof ninja1.swingSword); // 'function'

And, if ninja1 actually does have a swingSword, it probably means that it was created before the prototype was changed.

Objects retain their own [[Prototype]] reference from when they were created regardless of what changes may be made to their constructor's prototype property.

Ninja.prototype.swingSword = function() {
    alert("I can swing my sword.");
}

var ninja1 = new Ninja();

Ninja.prototype = new Person(); // won't affect existing instances

var ninja2 = new Ninja();

console.log(typeof ninja1.swingSword); // function
console.log(typeof ninja2.swingSword); // undefined

Example of each: http://jsfiddle.net/G8uTk/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top