繁体   English   中英

object.create如何在JavaScript中工作?

[英]How does object.create work in JavaScript?

告诉我,如果我错了:

原型是普通对象。 当一个对象继承原型时,它不仅仅复制原型的属性,该对象存储对原型的引用。

在Firefox中,我可以这样做:

var food = {fruit:"apple"};
var more_food = {vegetable:"celery"};
food.__proto__ = more_food;
food.vegetable // celery
food.fruit // apple

我可以使用__proto__属性手动设置对原型对象的引用。

我也可以使用Object.create

var food = {fruit:"apple"};
var more_food = {vegetable:"celery"};
food = Object.create(more_food);
food.vegetable // celery
food.fruit // undefined

Object.create究竟在做什么? 变量食物是否分配了对原型more_food的引用,或者是Object.create只返回对象的副本more_food? 如果Object.create只是制作副本,那么如果变量食物没有引用more_food,原型链如何工作?

原型是普通对象。 当一个对象继承原型时,它不仅仅复制原型的属性,该对象存储对原型的引用。

你是对的,一个对象的原型,只是通过原型链引用的另一个对象。

你的两个片段之间的区别在于__proto__你正在改变 food的原型。 在你的第二个例子中,你只是指定一个继承自more_food的新对象,这就是为什么food.fruit被解析为undefined的原因,因为你的原始food对象被该赋值丢失

Object.create究竟在做什么?

Object.create构建一个新对象 ,该对象继承自作为其第一个参数传递的对象(它可以只是一个对象或null )。

变量食物是否分配了对原型more_food的引用,或者是Object.create只返回对象的副本more_food?

你的food变量将保存一个新对象,它继承自more_food ,在这个操作中没有任何复制。

例如:

var food = {fruit:"apple"};
var more_food = Object.create(food, {
  vegetable: { value: "celery" }
});

more_food.fruit;     // "apple"
more_food.vegetable; // "celery"

在上面的例子中, more_food继承自food ,换句话说, foodmore_food的原型,这种原型参考存储在一个名为[[Prototype]]的内部属性中。 Object.create的第二个参数允许您初始化此新对象的属性。

没有复制,只是上面例子中的普通委托 more_food.fruit可以通过原型链访问,属性查找过程非常简单,如果在对象上找不到属性,它会再次查找(委托!)对象的原型,递归地,直到找到原型为null的对象(如Object.prototype )。

所以, more_food.fruit是一个继承的属性:

more_food.hasOwnProperty('fruit'); // false, inherited
'fruit' in more_food;              // true

虽然vegetablemore_food自有财产

more_food.hasOwnProperty('vegetable'); // true

上面的例子看起来像这样:

+---------------------+  [[Prototype]]  +---------------+
  | more_food           |+--------------->| food          |
  |---------------------|                 |---------------|
  | vegetable: "celery" |                 | fruit: "apple |
  +---------------------+                 +---------------+

如果Object.create只是制作副本,那么如果变量食物没有引用more_food,原型链如何工作?

Object.create不会创建对象的副本,它只是在创建新对象时设置它的原型。

请记住, __proto__是一个非标准功能,它将来会从实现中删除,已经在Mozilla文档中被列为已弃用 ,这是其主要原因,这也是该语言可能永远不会有的原因。以__proto__的方式改变原型链的方法是,它会导致VM和JIT级别的优化和安全问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM