3

Say we create a Function named 'Shape', and add a property 'name' & method 'toString' on it's prototype:

var Shape = function () {};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function () {
    return this.name;
}

console.log(Shape.name); // ''
console.log(Shape.toString()); // function () {}

var Triangle = new Shape();
console.log(Triangle.name); // 'Shape'
console.log(Triangle.toString()); // 'Shape'

'NEW' operator did two things: 1. It points this to 'Triangle' 2. It points 'Triangle's [[proto]] to Shape.prototype

Then I can understand when I call name & toString on Triangle, it searches for it's prototype chain till Shape.prototype.

But my problem is why not Shape searching for it's property(even it's an Object) for the method & property?

Thanks.

4
  • Properties are resolved on the internal [[Prototoype]] chain, not the public prototype. See also ECMA-262 13.2 Creating Function Objects. Commented Jul 24, 2014 at 4:28
  • "new Shape()" creates a new object, adds the property __proto__ to it and sets it to Shape.prototype. Shape however only has an empty __proto__. The "prototype chain" uses __proto__, not prototype. Commented Jul 24, 2014 at 4:29
  • @SpiderPig—there is no __proto__. Commented Jul 24, 2014 at 4:31
  • There is. At least in Chrome and Firefox. Open the console and type in "abc".__proto__ === String.prototype Commented Jul 24, 2014 at 4:34

3 Answers 3

3

When you access a property on an object, Javascript looks first directly on the object for any properties that have been added directly to the object (these are called "own" properties). If it doesn't find the property there, then it looks up the prototype chain.

So, when you do this:

var Triangle = new Shape();
console.log(Triangle.toString()); // 'Shape'

it looks for the .toString() property on the actual object named Triangle, but there is no property by that name directly on that object. So, since it didn't find anything on the object directly, it then looks on the prototype and it finds the Shape.prototype.toString() implementation there and that is what is executed.

A reference to the prototype is stored on the Triangle object when it is created. It is not stored in the .prototype property - that property is only used on the constructor. Instead, each JS version has its own way of storing a reference to the prototype and it has traditionally not been the same for all browsers and how it was stored was non-standard. It was originally meant only for internal use by the JS engine. For example, Chrome stores it on a property named obj.__proto__, but IE does not. To fix this lack of standardization, there is new method called obj.getPrototypeOf() which can now be used in modern browsers to get access to the prototype for a given object. In any case, the JS engine searches this prototype for you automatically when resolving property names that are not found on the actual object itself.

If you did this:

var Triangle = new Shape();
Triangle.toString = function() {
    return 'Shape named Triangle';
}
console.log(Triangle.toString()); // 'Shape named Triangle'

Then, javascript would first find the toString() implementation that you attached directly to the object and it would execute that one rather than the one on the prototype.

Sign up to request clarification or add additional context in comments.

8 Comments

yeah, as you say: "When you access a property on an object, Javascript looks first directly on the object for any properties that have been added directly to the object." As prototype is also a property of Shape, what not search the prototype obj for methods & properties, or it's not added directly? thanks.
@klamtlne - I really don't understand what else you're asking with that comment. I thought I explained it pretty clearly in my answer. The prototype itself is a special property that is not initially searched as it is 2nd in line to satisfy the request. If no match elsewhere on the object is found, THEN the prototype is searched for a match. That's how Javascript works and there are many reasons for it to work that way.
@jfiend00 The property of js object which stores property constructor, let's call it prototype(or obj.prototype). The Function we inherited(here is Shape), we have a [[proto]] property(in ff & chrome is __proto__)links to it, let's just call it obj.__proto__. I suppose the above answer you mean obj.__proto__ here, so when we store properties/methods in obj.prototype and call it, why js not search in that? (Additional, english is not my first language, I'll try to explain as clearly as I can, tks)
JS does search the prototype. Why do you say that it doesn't? obj.__proto__ (or what is returned by obj.getPrototypeOf()) contains a reference to the prototype and that's how JS knows which prototype to look at.
I just come to realize it. It does search [[prototype]], but it doesn't search property prototype.
|
1

So I am adding according to what I know.

Here Shape is a function & A function is just a special kind of object, and like any object a function can have properties.

Functions automatically get a property called prototype, which is just an empty object. This object gets some special treatment.

When you will do a new of a Function the created object inherits all of the properties of its constructor’s prototype.

Like bellow

var Shape = function () {};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function () {
    return this.name;  
}

When you will say

var Triangle = new Shape();

So what it does

var Triangle = {};
Triangle.name = Shape.prototype.name
Triangle.toString = Shape.prototype.toString;

"it sets up the object Triangle to delegate to Shape.prototype."

So when you will do

Triangle.name //Shape
Triangle.toString() // Shape

But for Shape you will have to say

Shape.prototype.name //Shape
Shape.prototype.toString() //Shape

1 Comment

I just come to realize it, Shape.prototype is nothing but a property, there is no reason JS search methods/properties in it, tks!
0

because Triangle is an object, where Shape is a function (a kind of an object), therefore when you request for a property of a function and it will not find it, will not search throught it's prototype propery. But you can modify Function.prototype.name/toSTring()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.