0

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?

dz210
  • 748
  • 1
  • 8
  • 20
  • Possible duplicate of [\_\_proto\_\_ VS. prototype in JavaScript](http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript) – rockerest Nov 05 '15 at 16:22

2 Answers2

1

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.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • I see - so with my code I can access the new property from any function, but because instances of String are not Functions, they do not inherit this property? – dz210 Nov 05 '15 at 17:50
  • @dz210, That's right. All *o* are instances of their constructor, and each of their prototypes' constructors, but not of their constructor's constructor. – Mike Samuel Nov 05 '15 at 18:18
1

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?

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • Not exactly - what I was wondering was why using the __proto__ property did not result in expected behavior. – dz210 Nov 05 '15 at 20:06