使用 Object.create 时无法枚举属性
Cannot enum properties when using Object.create
我有一个像这样的对象
var Profile = Object.create(null);
Object.defineProperties(Profile, {
id: {
value: "",
enumerable: true
},
name: {
value: "",
enumerable: true
},
active: {
value: true,
enumerable: true
}
});
现在我想创建一个配置文件实例并为其提供 id 和名称,并保持活动默认值为 true,所以我这样做:
var p1 = Object.create(Profile, {
id: {
value: "123",
enumerable: true
},
name: {
value: "hello world",
enumerable: true
}
});
然后我得到了一个名为 p1 的对象,但我在
Object.getOwnPropertyNames(p1);
我也不能使用 JSON.stringify(p1) 来序列化属性"active",但我需要属性"active"可以序列化。
这是我使用 Object.create 的错误方式吗?我只想创建一个可序列化的"类"并获取它的可序列化"实例"。我该怎么做?
由于您使用了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
对象不知道在 Profile
上定义了 active
属性。
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!
查看我上一条评论中的链接,以获取有关此事的更多详细信息
从 getOwnPropertyNames 上的 MDN 页面:
返回直接找到的所有属性(可枚举或不可枚举)的数组 在给定对象上。
活动属性位于 p1 的原型对象上,而不是 p1 上。
您可以使用 for in
构造迭代 p1 的所有属性(包括原型链上的属性)。要创建平面对象,您可以执行以下操作:
for (var key in obj) {
if (!obj.hasOwnProperty(key)) {
obj[key] = obj[key];
}
}
Object.getOwnPropertyNames
:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
for in
:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
Object.create
:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
- 不可枚举的属性出现在 for..在 Chrome 中循环
- JSON.stringify未序列化可枚举属性
- Javascript不可枚举属性
- 如何更改 Javascript 对象属性的可写可枚举和可配置值
- 无法在 javascript 中枚举对象的所有属性
- 枚举本地存储属性
- 为什么在枚举属性/函数时键长度不准确
- 遍历所有不可枚举属性的任意方法
- 断言对象上存在可枚举属性
- 在默认情况下将可枚举设置为 false 的 JS 中创建对象属性的其他方法是什么
- 使用 Object.create 时无法枚举属性
- 对不可枚举属性进行迭代
- 使用forEach枚举属性和值
- 如何在IE8的JavaScript中添加不可枚举属性
- 在Javascript中随机选择对象的可枚举属性
- 在angular js的select下拉菜单中访问枚举属性
- 扩展具有不可枚举属性的对象
- JavaScript和/或JSON要求解析器按定义顺序枚举属性吗?
- 可枚举属性与数组
- 为什么JSON.字符串化而不是序列化非枚举属性