简体   繁体   中英

Javascript `new` operator & prototype

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.

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.

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

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM