了解Crockford的Object.create垫片

时间:2012-04-13 12:44:32

标签: javascript prototype object-create

我一直在阅读Crockford垫片,以防止覆盖原型,并了解它有时不是最终/全部解决方案。我也明白ES5 Shim可能是一个可行的替代方案。我还阅读了this post which provides a more robust, secure alternative

不过,我想知道他的Object.create垫片是什么“说”然后“做”。有人可以告诉我,如果我的解释评论是正确的吗?

if (typeof Object.create === 'undefined') { 
//If the browser doesn't support Object.create

  Object.create = function (o) {
  //Object.create equals an anonymous function that accepts one parameter, 'o'.

    function F() {};
    //Create a new function called 'F' which is just an empty object.

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

    return new F();
    //create a new constructor function based off of the 'F' function.
  };
}

//Then, based off of the 'Lost' example in the Crockford book...

var another_stooge = Object.create(stooge);

//'another_stooge' prototypes off of 'stooge' using new school Object.create.
//But if the browser doesn't support Object.create,
//'another_stooge' prototypes off of 'stooge' using the old school method.

这样,当我们将东西扩充到'another_stooge'时,'stooge'对象的原型不能被覆盖。无需使用'构造函数'重置'stooge'原型。

提前致谢,

-k

5 个答案:

答案 0 :(得分:14)

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

在上面的示例中,我们使用newObject方法创建了一个新对象create,该方法是我们在Object中添加的Object对象的成员函数在我们(Crockford的)例子中早些时候的对象。基本上它是这样做的,create方法声明了一个函数F,一个空对象every function is a first class object in javascript,然后我们继承了o的原型(在这种情况下) o也是作为create method参数传递的对象oldObject,最后我们使用return new F();将新对象(F的实例)返回给变量{{1} },所以现在newObject是继承newObject的对象。现在,如果您编写oldObject,那么它会输出console.log(newObject.prop);,因为我们的Property_one对象已继承newObject,这就是我们获得oldObject值的原因为prop。这被称为原型继承。

您必须将对象作为Property_one方法

的参数传递

答案 1 :(得分:0)

它所做的只是创建一个新的对象构造函数,即F,然后将传递的对象分配给构造函数prototype属性,以便使用F构造函数创建的新对象继承这些方法。

然后使用构造函数返回一个新的初始化对象(new F()=> F.prototype)

但是crockford无法正确地重新分配构造函数,因为通常新对象构造函数应该与它继承的对象构造函数相同。

答案 2 :(得分:0)

关于你的意见:

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

最好说一个函数已分配给create的{​​{1}}属性。所有函数都可以被认为是匿名的,只是有些被分配给命名属性或变量,而其他函数则没有。

Object

声明一个函数。是的,它也是一个对象。

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

> F.prototype = o; > //the prototype of the 'F' function should point to the > //parameter of the anonymous function. 分配给o的引用要短一些。

F.prototype

不,应该是“返回F的实例”。因此返回的对象有一个内部> //create a new constructor function based off of the 'F' function. ,它引用传递给函数的对象。混乱的部分是必须创建一个无用的F函数来执行该技巧,并且返回的对象的构造函数将没有有用的值,因为它引用空[[Prototype]]

无论如何,构造函数属性都不是非常可靠或特别有用。

  

这样,'stooge'对象的原型不能被覆盖   当我们将东西增加到'another_stooge'时。无需重置   'stooge'原型使用'构造函数'。

这是一个奇怪的陈述。 * another_stooge *有F,因为它是私有的stooge,它不会从[[Prototype]]继承,而是从stooge.prototype继承。

如果您希望stooge.[[Prototype]]继承another_stooge,请使用stooge.prototypeObject.create(stooge.prototype),前者可能更合适。

我希望一切都有道理。

答案 3 :(得分:0)

这里有两个技巧:

  1. F不是一个简单的函数,它是一个构造函数。
  2. “F.prototype”只是一个属性,在这一刻它对继承没有任何作用。 真正的诀窍是当我们使用“new F()”时,“new”创建一个新对象,调用构造函数(这里不做任何事情)并设置新对象的内部“prototype”字段,其值为“ F.prototype“,因此返回的对象将继承自”o“。
  3. 所以我想,那:

    • F是构造函数
    • F不是从o
    • 继承
    • “new F”(返回的对象)继承自o

答案 4 :(得分:-1)

我想将内部函数命名为Object而不是F会使得生成的对象看起来更接近于Object.create()所创建的内容。

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