简体   繁体   中英

confusion about javascript exercise

I just got Javascript: The Good Parts by Douglas Crockford and I'm having some difficulty understanding one of his examples regarding prototypes. The code in the book reads as follows:

if (typeof Object.create !== "function") {
    Object.create = function(o) {
        var F = function () {}
        F.prototype = o;
        return new F;
    };
}

I'm assuming that this code is used to target a function's prototype. But why use such a complex approach? Why not just use variable .prototype? Crockford is the leading expert on Javascript so I'm sure there is a good reason for using this model. Can anyone help me understand it better? Any help would be appreciated.

In ECMAScript 3, the new operator was the only standard way to set the [[Prototype]] internal property of an object, in this case, Crockford is just using a temporary constructor function F for that purpose.

The o argument of that method, is set as the prototype property of the temporary constructor, and by invoking new F(); it builds a new empty object that inherits from F.prototype (see this question for more details about how new works).

For example:

var a = { a: 1 };
var b = Object.create(a); // b inherits from a
b.a; // 1

In the above example, we can say that the b 's internal [[Prototype]] property points to a .

Object.getPrototypeOf(b) === a; // true

In other words, b inherits from a .

With the same example, we could use an empty constructor, eg:

 function F(){}
 F.prototype = a;

 var b = new F(); // b again inherits from a (F.prototype)

Remember also that the prototype property of functions is different than the [[Prototype]] property that all objects have, the prototype property of functions is used when they are called with the new operator, to build a new object that inherits from that property.

Also, be aware that now, the ECMAScript 5 Standard is being implemented, and this shim, doesn't conform 100% with the spec, in fact, there are some features of the standard Object.create method that cannot be emulated on ES3 .

See also:

var bar = Object.create(foo)

vs.

var bar = new Object()

the first bar has foo as its prototype; the second has Object as its prototype.

This code is for older JavaScript implementations that do not support Object.create , which is specified in the ECMAScript 5 standard released in November 2009.

Many people say the preferred way to create an object is to specify a prototype for it at the time of creation. This can be called differential inheritance or prototypal inheritance . In fact, that is what Object.create does:

var protoCircle = {x: 0, y: 0, radius: 1, color:"black"};
var myCircle = Object.create(protoCircle);
myCircle.x = 3;
myCircle.color = "green";

This make a green circle of radius 1 centered at (3,0).

The reason the code is so complex that before Object.create was added to JavaScript, the only way to set an object's prototype was to create it with the new operator . Objects created with new got, as their prototype, the value of the constructor's prototype property. It's definitely confusing, but the prototype property is NOT the prototype of an object. Given a function object f , f.prototype is the object that will be assigned as the prototype of all objects constructed through new f() . An object's real prototype is called [[prototype]] or __proto__ but you cannot access these in standard ECMAScript. Confusing, eh?

As a side note. the ES5 specification has a more enhanced Object.prototype specification than the one Crockford defined. It takes a second object for configuring properties of the object being defined.

给定传递的对象作为原型,此create方法将实例化一个新对象。

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