对象。getOwnPropertyNames vs Object.keys

在javascript中,Object.getOwnPropertyNamesObject.keys有什么区别?还有一些例子,将赞赏。

72518 次浏览

有一点不同。Object.getOwnPropertyNames(a)返回对象所有自己的属性aObject.keys(a)返回所有可列举的自己的属性。这意味着如果你定义对象属性而不使其中一些属性enumerable: false,这两个方法会给你相同的结果。

很容易测试:

var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 1},
two: {enumerable: false, value: 2},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]

如果你定义一个属性而没有提供属性属性描述符(意味着你不使用Object.defineProperties),例如:

a.test = 21;

然后,该属性自动变成可枚举的,两个方法生成相同的数组。

另一个区别是(至少在nodejs中)"getOwnPropertyNames"函数不保证键的顺序,这就是为什么我通常使用"keys"函数:

    Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});

另一个区别是在数组Object.getOwnPropertyNames的情况下,方法将返回一个额外的属性length

var x = ["a", "b", "c", "d"];
Object.keys(x);  //[ '0', '1', '2', '3' ]
Object.getOwnPropertyNames(x);  //[ '0', '1', '2', '3', 'length' ]

这里有一些东西让我。

const cat1 = {
eat() {},
sleep() {},
talk() {}
};


// here the methods will be part of the Cat Prototype
class Cat {
eat() {}
sleep() {}
talk() {}
}


const cat2 = new Cat()


Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []


Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]


cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}


// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
var propNames = Object.keys(Obj);


// I was missing this if
// if (propNames.length === 0) {
//     propNames = Object.getOwnPropertyNames(Obj);
// }


for (var prop in propNames) {
var propName = propNames[prop];


APIObject[propName] = "reasign/redefine or sth";
}
}

因此,在我的例子中,如果我给foo函数提供cat2类型的对象,它就不起作用。

还有其他方法来创建对象所以这里也可能有其他的扭结。

如前所述,.keys不返回不可枚举的属性。

关于例子,其中一个陷阱案例是Error对象:它的一些属性是不可枚举的。
所以当console.log(Object.keys(new Error('some msg')))产生[]时, console.log(Object.getOwnPropertyNames(new Error('some msg')))产生["stack", "message"]

console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));