Understanding Crockford's Object.create shim

后端 未结 5 1486
后悔当初
后悔当初 2020-11-28 14:44

I\'ve been reading up on the Crockford shim for preventing the overwriting of prototypes, and understand that it\'s not the end-all/be-all solution at times. I also underst

相关标签:
5条回答
  • 2020-11-28 15:05

    There are two tricks here:

    1. F is not a simple function, it is a constructor.
    2. "F.prototype" is just a property, it does nothing with inheritance in this moment. The real trick is that when we use "new F()", the "new" creates a new object, calls the constructor (which does not do anything here) AND sets the new object's internal "prototype" field with the value of "F.prototype", so the returned object will inherit from "o".

    So I think, that:

    • F is a constructor
    • F is not inherit from o
    • "new F" (which is the returned object) is inherit from o
    0 讨论(0)
  • 2020-11-28 15:13

    On your comments:

    >   //Object.create equals an anonymous function that accepts one parameter, 'o'.
    

    Better to say that a function is assigned to the create property of Object. All functions can be considered anonymous, just that some are assigned to named properties or variables, others aren't.

    > //Create a new function called 'F' which is just an empty object.
    

    Declare a function. Yes, it's an object too.

    >     F.prototype = o;
    >     //the prototype of the 'F' function should point to the
    >     //parameter of the anonymous function.
    

    A reference to o is assigned to F.prototype is a bit shorter to write.

    >     //create a new constructor function based off of the 'F' function.
    

    No, should be "Return an instance of F". So the returned object has an internal [[Prototype]] that references the object passed to the function. The messy part is that a useless F function had to be created to perform the trick, and the returned object's constructor will not have a useful value as it references the empty F.

    Not that the constructor property is very reliable or particularly useful normally anyway.

    This way, the prototype of the 'stooge' object can't be overwritten when we augment stuff to 'another_stooge'. No need to reset the 'stooge' prototype using 'constructor'.

    That's a strange statement. *another_stooge* has stooge as it's private [[Prototype]], it does not inherit from stooge.prototype but from stooge.[[Prototype]].

    If you want another_stooge to inherit from stooge.prototype, use Object.create(stooge.prototype) or Object.create(new stooge()), the former is probably more suitable.

    I hope that all makes sense.

    0 讨论(0)
  • 2020-11-28 15:16

    All it does is create a new object constructor, which is F, it then assign the passed object to the constructor prototype property so that new object created with the F constructor inherit those methods.

    It then use the constructor to return an newly initialize object (new F() => F.prototype)

    But the crockford one fail to reassign the constructor properly as normally the new object constructor should be the same as the object constructor it inherits from.

    0 讨论(0)
  • 2020-11-28 15:18
    if (typeof Object.create !== 'function') {
        Object.create = function (o) {
            function F() {}
            F.prototype = o;
            return new F();
        };
    }
    var oldObject={prop:'Property_one' }; // An object
    var newObject = Object.create(oldObject); // Another object
    

    In the above example we've created a new object newObject using create method which is a member function of Object object that we've added in the Object object earlier in our (Crockford's) example. So basically what it does is that, the create method declares a function F, an empty object every function is a first class object in javascript and then we've inherited the prototype of o (in that case o is also an object oldObject passed as the parameter of create method) and finally we've returned the new object (an instance of F) using return new F(); to the variable newObject, so now newObject is an object that inherited the oldObject. Now if you write console.log(newObject.prop); then it'll output Property_one because our newObject object has inherited the oldObject and that's why we've got the value of prop as Property_one. this is known as prototypical inheritance.

    You must pass an object as the parameter of create method

    0 讨论(0)
  • 2020-11-28 15:28

    I guess naming the internal function as Object instead of F makes the resulting object look closer to what Object.create() would create.

    if (typeof Object.create !== 'function') {
        Object.create = function (o) {
            function Object() {}
            Object.prototype = o;
            return new Object();
        };
    }
    
    0 讨论(0)
提交回复
热议问题