了解Crockford的Object.create垫片
我一直在阅读Crockford垫片,以防止重写原型,并且明白这不是最终所有/全部的解决scheme。 我也明白, ES5 Shim可能是一个可行的替代scheme。 我也读这篇文章,提供了一个更强大,更安全的select 。
不过,我想知道他的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
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
在上面的例子中,我们使用create
方法创build了一个新对象newObject
,它是Object
对象的一个成员函数,我们在前面的(Crockford的)例子中已经添加了Object
对象。 所以基本上它是这样做的, create
方法声明一个函数F
,一个空的对象every function is a first class object in javascript
,然后我们inheritance了o
的原型(在这种情况下, o
也是一个对象oldObject
传递为create方法的参数),最后我们返回新的对象(F的一个实例),使用return new F();
到variablesnewObject
,所以现在newObject
是一个inheritanceoldObject
的对象。 现在如果你写了console.log(newObject.prop);
那么它会输出Property_one
因为我们的newObject
对象已经inheritance了oldObject
,这就是为什么我们把prop
的值作为Property_one
。 这被称为原型inheritance。
您必须传递一个对象作为create
方法的参数
它所做的只是创build一个新的对象构造函数,即F,然后将传递的对象分配给构造函数prototype属性,以便使用F构造函数创build的新对象inheritance这些方法。
然后使用构造函数返回一个新的初始化对象(new F()=> F.prototype)
但是crockford不能正确地重新分配构造函数,因为新的对象构造函数应该和它inheritance的对象构造函数一样。
在你的评论:
> //Object.create equals an anonymous function that accepts one parameter, 'o'.
更好的说,一个函数被分配给Object
的create
属性。 所有的function都可以被认为是匿名的,只是有些被分配给命名的属性或variables,其他的则不然。
> //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]]
。 凌乱的部分是必须创build一个无用的F函数来执行这个技巧,并且返回的对象的构造函数没有一个有用的值,因为它引用了空F
不是说构造函数属性通常是非常可靠或特别有用的。
这样,当我们把东西加到another_stooge时,'stooge'对象的原型不能被覆盖。 不需要使用“构造函数”重置“stooge”原型。
这是一个奇怪的说法。 * another_stooge *有stooge
因为它是私有的[[Prototype]]
,它不是从stooge.prototype
inheritance,而是从stooge.[[Prototype]]
inheritance。
如果你想让another_stooge
从stooge.prototype
inheritance,使用Object.create(stooge.prototype)
或Object.create(new stooge())
,前者可能更合适。
我希望一切都有道理。
这里有两个技巧:
- F不是一个简单的函数,它是一个构造函数。
- “F.prototype”只是一个属性,在这个时候它并没有与inheritance有关。 真正的诀窍是,当我们使用“new F()”时,“new”创build一个新的对象,调用构造函数(这里什么都不做),并设置新对象的内部“prototype”字段的值为“ F.prototype“,所以返回的对象将从”o“inheritance。
所以我认为:
- F是一个构造函数
- F不是从oinheritance而来的
- “新F”(这是返回的对象)从oinheritance
我猜想将内部函数命名为Object
而不是F
使得生成的对象更接近Object.create()
将创build的内容。
if (typeof Object.create !== 'function') { Object.create = function (o) { function Object() {} Object.prototype = o; return new Object(); }; }