10

我一直在阅读 Crockford 垫片以防止覆盖原型,并了解它有时不是最终/全部解决方案。我也明白ES5 Shim可能是一个可行的替代方案。我还阅读了这篇文章,它提供了更强大、更安全的替代方案

尽管如此,我还是想知道他的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”对象的原型就不会被覆盖。无需使用 'constructor' 重置 'stooge' 原型。

提前致谢,

-k

4

5 回答 5

15
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使用方法创建了一个新对象,该方法是我们之前在(Crockford 的)示例中添加到对象中的对象create的成员函数。所以基本上它的作用是,该方法声明一个函数,一个空对象,然后我们继承了原型(在这种情况下也是作为 create 方法的参数传递的对象),最后我们返回了新的对象(F 的一个实例)使用到变量,所以 now是一个继承了. 现在如果你写那么它会输出,因为我们的对象继承了ObjectObjectcreateFevery function is a first class object in javascriptoooldObjectreturn new F();newObjectnewObjectoldObjectconsole.log(newObject.prop);Property_onenewObjectoldObject这就是为什么我们有propas的价值Property_one。这被称为原型继承。

您必须将对象作为create方法的参数传递

于 2012-04-13T13:57:25.073 回答
0

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

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

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

于 2012-04-13T12:56:26.837 回答
0

关于您的评论:

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

最好说一个函数被分配给 的create属性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写起来有点短。

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

不,应该是“返回 F 的实例”。所以返回的对象有一个内部[[Prototype]]引用传递给函数的对象。混乱的部分是必须创建一个无用的 F 函数来执行该技巧,并且返回的对象的构造函数将没有有用的值,因为它引用了 empty F

并不是说构造函数属性通常非常可靠或特别有用。

这样,当我们将东西扩充到“another_stooge”时,“stooge”对象的原型就不会被覆盖。无需使用 'constructor' 重置 'stooge' 原型。

这是一个奇怪的说法。*another_stooge*stooge因为它是私有的[[Prototype]],所以它不是继承自stooge.prototype而是继承自stooge.[[Prototype]].

如果你想another_stooge继承自stooge.prototype,使用Object.create(stooge.prototype)or Object.create(new stooge()),前者可能更合适。

我希望一切都说得通。

于 2012-04-13T13:45:47.870 回答
0

这里有两个技巧:

  1. F 不是一个简单的函数,它是一个构造函数。
  2. “F.prototype”只是一个属性,此时它与继承无关。真正的诀窍是,当我们使用“new F()”时,“new”会创建一个新对象,调用构造函数(这里不做任何事情)并将新对象的内部“prototype”字段设置为“ F.prototype”,因此返回的对象将继承自“o”。

所以我认为:

  • F 是构造函数
  • F 不是继承自 o
  • “new F”(即返回的对象)继承自 o
于 2013-04-04T20:05:02.490 回答
-1

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

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function Object() {}
        Object.prototype = o;
        return new Object();
    };
}
于 2016-09-20T08:41:20.903 回答