使用Object.create时无法枚举属性

时间:2013-09-20 12:17:08

标签: javascript object serialization ecmascript-5

我有像

这样的对象
var Profile = Object.create(null);
Object.defineProperties(Profile, {
    id: {
        value: "",
        enumerable: true
    },
    name: {
        value: "",
        enumerable: true
    },
    active: {
        value: true,
        enumerable: true
    }
});

现在我想创建一个Profile实例并给它id和name,并保持active default为true,所以我这样做:

var p1 = Object.create(Profile, {
    id: {
        value: "123",
        enumerable: true
    },
    name: {
        value: "hello world",
        enumerable: true
    }
});

然后我得到了一个名为p1的对象,但我在

中找不到“active”
Object.getOwnPropertyNames(p1);

此外,我不能使用JSON.stringify(p1)序列化属性“active”,但我需要属性“active”可以序列化。

这是我使用Object.create的错误方法吗?我只想创建一个可序列化的“类”并获得它的可序列化“实例”。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

来自getOwnPropertyNames的MDN页面:

  

返回直接找到的所有属性(可枚举或不可枚举)的数组   在给定的对象上。

活动属性位于p1的proto对象上,而不是p1上。

您可以使用for in构造迭代p1的所有属性(包括原型链上的属性)。要创建平面对象,可以执行以下操作:

for (var key in obj) {
  if (!obj.hasOwnProperty(key)) {
    obj[key] = obj[key];
  }
}

Object.getOwnPropertyNameshttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames

for inhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

Object.createhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

答案 1 :(得分:1)

由于您使用Object.create,您实际上并未将任何内容克隆/复制到生成的对象中(您调用p1)。首先,您必须了解JS在访问对象属性时如何解析它们:

J [     p1.active     ]<=========================================================\ \
S p1[active] ==> JS checks instance for property divide                           | |
O  /\ ||                                                                          | |
N  || || --> property found @instance? return value-------------------------------| |
=  || ||                                                                          | |
   || ===========> p1.prototype is found: Profile, check that object              | |
N  ||      ||                                                                     | |
O  ||      ||--> Profile.active found @Profile instance, return-------------------| |
T  ||      ||                                                                     | |
   ||      ==========> Profile.prototype.active (== Object.prototype.active)      | |
J  ||          ||                                                                 | |
S  ||          ||--> property found @Object.prototype, return---------------------|_|
O  ||          ||                                                                 |=|
N  ||          =======>prototype is null, return "undefined.active"~~~~~~~~~~~~~~~|X|
   ||                                                                             \ /
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined

基本上,会发生什么。现在,在调用JSON.stringify(p1)时,JS将转向p1对象,并处理其属性(定义为@instance级别的属性)。 p1对象不知道在active 上定义了Profile属性。
JSON.stringify仅检查我用JSON标记的步骤(第一个循环),所有其他检查(原型链)对JSON不感兴趣。 9月10日,这只是Object.prototype,你不想把它串起来,现在好吗?

粗暴地说,对于你(看似)想要完成的事情,最简单的解决方案就是:

p1 = JSON.parse(JSON.stringify(Profile));
p1.id = 123;
p1.name = 'hello world';
console.log(JSON.stringify(p1));//will show active property!

检查我上次评论中的链接,了解有关此问题的详细信息