dz210
dz210

Reputation: 768

Understanding Javascript prototype chains

If I have an instance of a String, and I modify its constructor's prototype, then the prototype of every String instance has that property (as expected).

 "test string".constructor.prototype.thing = function() {return this;}
 console.log("new string".thing());//prints "new string"

However, if I modify the String constructor's constructor's prototype, then this no longer works:

String.constructor.prototype.thing = function() {return this;}
console.log("new string".thing());//returns "new string".thing() is not a function

Same thing if I use the String.proto syntax. Why is this? I was under the impression that JavaScript will go all the way up the prototype chain when looking for a property. If I add a property to String.constructor.prototype, then String will not have that property, but its parent object will, correct? Therefore all instances of String should have access to that property as well. Where am I wrong in my thinking?

Upvotes: 0

Views: 81

Answers (2)

Tom Karzes
Tom Karzes

Reputation: 24052

If you want to create prototype chains longer than one, to support inheritance from a superclass, the normal way to do it is to set a constructor's prototype to a class instance which itself inherits from a prototype. The following example demonstrates this:

function c1(b) {
    this.b = b;
}
c1.prototype = {a:111};

x = new c1(222);

function c2(c) {
    this.c = c;
}
c2.prototype = x;

y = new c2(333);

alert(y.a + ", " + y.b + ", " + y.c);

The three variables in y are:

a   inherited from c1's prototype, via c2's prototype
b   inherited from c2's prototype
c   stored directly in y

Note that it follows the prototype chain up 2 levels to access a from y.

Is this what you were wondering how to do?

Upvotes: 1

Mike Samuel
Mike Samuel

Reputation: 120516

However, if I modify the String constructor's constructor's prototype, then this no longer works:

A constructor is a function, so any constructor's constructor is Function.

That means "the String constructor's constructor's prototype" is Function.prototype.

If you add something to Function.prototype it will appear as a member of any function, not as a member of any string.


You can play around with Object.getPrototypeOf to get an idea.

$ (Object.getPrototypeOf(Object(""))
String {length: 0, [[PrimitiveValue]]: ""}
$ Object.getPrototypeOf(Object.getPrototypeOf(Object("")))
Object {}
$ Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object(""))))
null

The object value of a primitive string is-a String which is-an Object which is the end of the prototype-chain.

Upvotes: 1

Related Questions