我刚刚得到了道格拉斯·克罗克福德的Javascript:The Good Parts,我在理解他的原型示例方面遇到了一些困难。书中的代码如下:
if (typeof Object.create !== "function") {
Object.create = function(o) {
var F = function () {}
F.prototype = o;
return new F;
};
}
我假设这段代码用于定位函数的原型。但为什么要使用这种复杂的方法呢?为什么不使用variable
。原型? Crockford是Javascript领域的领先专家,所以我确信有充分的理由使用这个模型。谁能帮助我更好地理解它?任何帮助将不胜感激。
答案 0 :(得分:5)
在ECMAScript 3中,new
运算符是设置对象的[[Prototype]]
内部属性的唯一标准方法,在这种情况下,Crockford只使用<为此目的,em>临时构造函数 F
。
该方法的o
参数设置为临时构造函数的prototype
属性,并通过调用new F();
构建一个从{{1}继承的新空对象(有关F.prototype
如何工作的详细信息,请参阅this question。
例如:
new
在上面的示例中,我们可以说var a = { a: 1 };
var b = Object.create(a); // b inherits from a
b.a; // 1
的内部b
属性指向[[Prototype]]
。
a
换句话说,Object.getPrototypeOf(b) === a; // true
继承自b
。
使用相同的示例,我们可以使用空构造函数,例如:
a
还要记住函数的 function F(){}
F.prototype = a;
var b = new F(); // b again inherits from a (F.prototype)
属性与所有对象具有的prototype
属性不同,函数的[[Prototype]]
属性在使用new运算符调用时使用,构建一个从该属性继承的新对象。
此外,请注意,现在,ECMAScript 5标准正在实施,并且此垫片不符合规范100%,事实上,标准prototype
方法{{{{{ 3}}。
另见:
答案 1 :(得分:3)
var bar = Object.create(foo)
VS。
var bar = new Object()
第一个bar
以foo
为原型;第二个以Object
为原型。
答案 2 :(得分:1)
此代码适用于不支持Object.create
的较旧JavaScript实现,differential inheritance
在2009年11月发布的ECMAScript 5标准中指定。
许多人说创建对象的首选方法是在创建时为其指定原型。这可以称为prototypal inheritance
或Object.create
。事实上,这就是var protoCircle = {x: 0, y: 0, radius: 1, color:"black"};
var myCircle = Object.create(protoCircle);
myCircle.x = 3;
myCircle.color = "green";
的作用:
Object.create
这使得半径为1的绿色圆圈以(3,0)为中心。
代码如此复杂以至于在new
添加到JavaScript之前,设置对象原型的唯一方法是使用new
运算符创建代码。使用prototype
创建的对象作为其原型获得了构造函数的prototype
属性的值。这绝对令人困惑,但f
属性不是对象的原型。给定一个函数对象f.prototype
,new f()
是将被指定为通过[[prototype]]
构造的所有对象的原型的对象。对象的真实原型称为__proto__
或Object.prototype
,但您无法在标准ECMAScript中访问它们。令人困惑,嗯?
作为旁注。 ES5规范比Crockford定义的规范具有更强的{{1}}规范。它需要第二个对象来配置正在定义的对象的属性。
答案 3 :(得分:0)
这个create方法将实例化一个新对象,并将传递的对象作为原型。