Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

javascript - What is happening in Crockford's object creation technique?

There are only 3 lines of code, and yet I'm having trouble fully grasping this:

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
newObject = Object.create(oldObject);

(from Prototypal Inheritance)

  1. Object.create() starts out by creating an empty function called F. I'm thinking that a function is a kind of object. Where is this F object being stored? Globally I guess.

  2. Next our oldObject, passed in as o, becomes the prototype of function F. Function (i.e., object) F now "inherits" from our oldObject, in the sense that name resolution will route through it. Good, but I'm curious what the default prototype is for an object, Object? Is that also true for a function-object?

  3. Finally, F is instantiated and returned, becoming our newObject. Is the new operation strictly necessary here? Doesn't F already provide what we need, or is there a critical difference between function-objects and non-function-objects? Clearly it won't be possible to have a constructor function using this technique.

What happens the next time Object.create() is called? Is global function F overwritten? Surely it is not reused, because that would alter previously configured objects. And what happens if multiple threads call Object.create(), is there any sort of synchronization to prevent race conditions on F?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1) Object.create() starts out by creating an empty function called F. I'm thinking that a function is a kind of object. Where is this F object being stored? Globally I guess.

No, it's stored on the local scope of the Object.create function, each time you invoke Object.create this function F will be recreated.

You could even create a more memory-efficient implementation, by storing F on a closure, and reuse it:

if (typeof Object.create !== "function") {
  Object.create = (function () {
    function F() {} // created only once
    return function (o) {
      F.prototype = o; // reused on each invocation
      return new F();
    };
  })();
}

2) Next our oldObject, passed in as o, becomes the prototype of function F. Function (i.e., object) F now "inherits" from our oldObject, in the sense that name resolution will route through it. Good, but I'm curious what the default prototype is for an object, Object? Is that also true for a function-object?

All objects have an internal property that builds the prototype chain, this property is known as [[Prototype]], it's an internal property, although some implementations let you access to it, like mozilla, with the obj.__proto__ property.

The default [[Prototype]] when you create a new object, i.e. var obj = {}; is Object.prototype.

All functions have a prototype property, this property is used when a function is used as a Constructor, invoked with the new operator.

A new object instance it's created behind the scenes, and this object [[Prototype]] is set to its Constructor's prototype property.

3) Finally, F is instantiated and returned, becoming our newObject. Is the "new" operation strictly necessary here? Doesn't F already provide what we need, or is there a critical difference between function-objects and non-function-objects? Clearly it won't be possible to have a constructor function using this technique.

Yes, the new operator is essential in this method.

The new operator is the only standard way to set the [[Prototype]] internal property of an object, if you are curious about how it works, you can give a look to the [[Construct]] internal operation.

What happens the next time Object.create() is called? Is global function F overwritten? Surely it is not reused, because that would alter previously configured objects. And what happens if multiple threads call Object.create(), is there any sort of synchronization to prevent race conditions on F?

The next time Object.create is invoked, a new local F function is instantiated only within the scope of the method call, you shouldn't worry about race conditions.

Note that this implementation hardly conforms the Object.create described in the ECMAScript 5th Edition Specification, in that method, you could pass a property descriptor to initialize the object.

All browser vendors are implementing it (already available on Firefox 3.7 alphas, latest Wekit Nightly Builds and Chrome 5 Beta), so I would recommend you at least to check if a native implementation exist before overriding it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...