【问题标题】:After Object.create: properties are there, but Object.keys / getOwnPropertyNames = []?Object.create: 属性之后有,但是 Object.keys / getOwnPropertyNames = []?
【发布时间】:2017-08-04 15:36:27
【问题描述】:

正如标题所说,我在理解 Object.create() 的工作原理时遇到了概念上的障碍。

我的印象是,使用此方法后,生成的对象将继承作为参数传递给 Object.create() 的对象的值。在下面的简单示例中,我可以创建一个对象并访问其继承值,甚至可以正确获取新对象的原型,但是 Object.keys() 数组为空!

let obj = Object.create({x: 1, y: 2});
console.log("Keys of obj:");
Object.keys(obj).forEach(function (key) {
  console.log(key + ' - ' + obj[key]);
});
console.log("Prototype of obj:");
console.log(Object.getPrototypeOf(obj));
console.log("obj.x = " + obj.x);

控制台结果:

acg@acg:~/dev/$ node test.js 
Keys of obj:
Prototype of obj:
{ x: 1, y: 2 }
obj.x = 1

(只是为了消除任何混淆:顺便说一下,用 Object.getOwnPropertyNames() 代替 Object.keys() 时,我得到了相同的结果)。

我是不是误会了什么?为什么keys数组是空的?

编辑:我是否正确假设 Object.keys() 和 Object.getOwnPropertyNames() 只给我对象上直接可用的属性,即不继承? 然后,我想我的问题是:有没有一个函数可以给我一个对象的属性? (继承或其他)

EDIT2:不——必须手动遍历原型链,如下所示: Is it possible to get the non-enumerable inherited property names of an object?

EDIT3:根据下面 Pol Martin 的回答,可以使用 for..in 构造遍历所有属性(包括继承的属性)。 另见https://stackoverflow.com/a/208439/7705625

【问题讨论】:

  • Object.keys 返回表示给定对象的所有可枚举属性的字符串数组。 继承的属性是不可枚举的。见Enumerability and ownership of properties查看底部表格。
  • @Tushar 是的,我的问题是:如果我可以访问 obj.x,为什么该数组和 getOwnPropertyNames 都是空的?
  • 短版:当你做 obj.x -> 首先它尝试在直接属性中找到 x,如果不可用,它会在父/原型中找到它。因此,在您的情况下返回的结果来自父级。
  • @inQstvJS 这很清楚。但是 keys() 或 getOwnPropertyNames() 是否也一样?我认为不是(请参阅我编辑的帖子)。我需要一种方法来查找对象的所有属性,无论是否继承。

标签: javascript object


【解决方案1】:

Object.create 有两个参数。第一个是创建对象的原型,第二个可选参数是属性描述符的对象。

Object.create(proto[, propertiesObject])

如果创建对象时将属性对象作为第一个参数传递,

let obj = Object.create({x: 1, y: 2});

这个将成为你的新对象的原型。 由于 Object.keys() 返回一个仅包含它自己的可枚举属性的数组,因此不会列出您在构造它时传递的那些。

要按照你想要的方式创建对象,你可以使用 Object.assign:

let obj = Object.assign({}, {x: 1, y: 2});

【讨论】:

  • 谢谢——我已经很怀疑了。有没有办法获取对象上定义的所有属性,无论它们是继承的还是其他的?还是我必须为此构建自己的原型链遍历?
  • 回答了我自己的问题:不,必须遍历链:stackoverflow.com/questions/8024149/…
  • 是的,你可以。如果您想要检索对象的所有属性,无论是自己的还是原型链上的,您可以使用 for .. in 循环:stackoverflow.com/a/208439/7705625
  • 有趣!所以 hasOwnProperty() 比 getOwnPropertyNames() 更了解整个链上可用的属性?将不得不尝试一下,听起来像我需要的。谢谢!
  • 我认为您在这里感到困惑。 hasOwnProperty 告诉您属性是否是对象本身的一部分而不是原型的一部分,getOwnPropertyNames 只返回作为对象一部分的所有属性,而不是原型。使这项工作按预期工作的是 for .. in 循环,它重新调整 所有 属性,无论是自己的还是来自原型的。然后使用 hasOwnProperty 你可以断言它们是来自对象还是来自原型链。
猜你喜欢
  • 2017-03-18
  • 2015-08-23
  • 1970-01-01
  • 2012-10-07
  • 2014-09-23
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
相关资源
最近更新 更多