JavaScript - passing an object literal as second arg to Object.create()

ぃ、小莉子 提交于 2019-12-19 03:54:14

问题


Referring to the JavaScript code snippet below, questions:

  1. Why does the object literal {item: {value: "foobar"}} behave differently when assigned to a variable (like in line 1) vs. when passed as an argument to Object.create() (like in line 5)?

  2. What is the difference between line 5 and line 8 - i.e. why is line 5 the correct way to pass the second argument to Object.create() and not line 8 (to override the item property in delegate)?

Code Snippet:

 1 var obj = {item: {value: "foobar"}};
 2 console.log(obj.item);            // [object Object]
 3 console.log(obj.item.value);      // foobar

 4 var delegate = {item: "xxx"};
 5 var obj1 = Object.create(delegate, {item: {value: "foobar"}});
 6 console.log(obj1.item);          // foobar
 7 console.log(obj1.item.value);    // undefined

 8 var obj2 = Object.create(delegate, {item: "bar"});
 9 console.log(obj2.item);          // <nothing>

回答1:


This happens because according to this reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create

Object.create receives an object with "property descriptors" as second argument, not plain key:value pairs.

See this blog post: http://ejohn.org/blog/ecmascript-5-objects-and-properties/ for a description of property descriptors.

A property descriptor is an object that describes each property, not just the property value. From your code snippet:

2 obj.item // [object Object] since item is the object {value:"foobar¨}

6 obj1.item // foobar, the descriptor says that the value 
            // of item is "foobar"

7 obj1.item.value // undefined since item="foobar", value is part of
                  // the object that describes "item" not item itself

9 obj2.item  // nothing because the descriptor that you passed 
             // for item is incomplete



回答2:


  1. In line 1 your object literal is interpreted literally and instantiated as you would generally expect.

    Whereas, in line 5, your object literal is interpreted literally, but is passed into the Object.create function where the instantiated object is treated as a "properties object containing property descriptors".

  2. Because the Object.create function expects it's second parameter to follow the "Properties Object" convention, your second parameter (on line 8) is invalid (causing a Type Error in Chrome).

The following snippet may help illustrate:

var PrototypeObj = { item: 'xxx' };

var PropertiesObj = {
  propertyDescriptor1: {
    value: "prop1value",
    writable: true,
    enumerable: true,
    configurable: true
  },
  propertyDescriptor2: {
    value: "prop2value",
    writable: true,
    enumerable: true,
    configurable: true
  }
};

var Obj = Object.create(PrototypeObj, PropertiesObj);

These articles go into greater detail: Object.create, Object.defineProperty.



来源:https://stackoverflow.com/questions/12015579/javascript-passing-an-object-literal-as-second-arg-to-object-create

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!