Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Object.getOwnPropertyNames vs Object.keys_Javascript - Fatal编程技术网

Javascript Object.getOwnPropertyNames vs Object.keys

Javascript Object.getOwnPropertyNames vs Object.keys,javascript,Javascript,javascript中的Object.getOwnPropertyNames和Object.keys之间有什么区别?还有一些例子将不胜感激。有一点不同对象。getOwnPropertyNames(a)返回对象a的所有自己的属性Object.keys(a)返回所有可枚举的自身属性。这意味着,如果定义对象属性而不使其中一些属性可枚举:false,这两种方法将得到相同的结果 很容易测试: var a = {}; Object.defineProperties(a, { one: {enumer

javascript中的
Object.getOwnPropertyNames
Object.keys
之间有什么区别?还有一些例子将不胜感激。

有一点不同<代码>对象。getOwnPropertyNames(a)返回对象
a
的所有自己的属性
Object.keys(a)
返回所有可枚举的自身属性。这意味着,如果定义对象属性而不使其中一些属性可枚举: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"]
如果在未提供属性属性描述符的情况下定义属性(表示不使用
对象.defineProperties
),例如:

a.test = 21;

然后,这样的属性会自动成为可枚举的,并且两种方法都会生成相同的数组。

另一个区别是(至少对于nodejs)“getOwnPropertyNames”函数不能保证键的顺序,这就是为什么我通常使用“keys”函数的原因:

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

另一个区别是数组
对象的情况。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";
    }
}
所以在我的例子中,如果我给它cat2类型的对象,那么
foo
函数就不能工作


还有其他方法可以创建对象,因此其中可能还有其他问题。

正如前面所解释的,
键不返回不可枚举的属性

关于示例,陷阱之一是
错误
对象:它的一些属性是不可枚举的。
所以当
console.log(Object.keys(新错误('some msg'))
产生
[]
)时,
console.log(Object.getOwnPropertyNames(新错误('some msg'))
产生
[“堆栈”,“消息”]

console.log(Object.keys(新错误('some msg'));

log(Object.getOwnPropertyNames(新错误('somemsg'))
从两者的MDN文章来看,区别在于,返回的列表是否包含不可枚举的属性:不返回,而返回。特别是数组对象的
length
属性不可枚举,因此它不会出现在
Object.keys
@Barmar中。对象的
length
属性在原型上,而不是对象本身,因此
Object.keys
Object.getOwnPropertyNames
都不会列出它。@qo指定
Object.getOwnPropertyNames(anyArray)的结果
包括
长度
我站着纠正
Object.getOwnPropertyNames(anyArray)
确实在返回的数组中包含
length
!是的,但是阵列,原型也有。有点奇怪,人们可以像修改普通数组一样修改Array.prototype(即Array.prototype.push('whatever'))。但它似乎对新创建的数组实例没有影响。在Node.js的当前版本中仍然是这样吗?如果是这样,您是否知道
getOwnPropertyNames
有任何不符合顺序的示例?因为ES2015是指定的,但仍然取决于实现。我一直认为JS对象键没有顺序,即使实现保持顺序,你也不应该依赖它?嗯,我认为相反;getOwnPropertyNames的顺序在规范中定义。Object.keys由实现决定。以下所有项都有未指定的顺序:
for in-loop
Object.keys
Object.getOwnPropertyNames
。也就是说,这三个对象都将按照彼此一致的顺序进行枚举。
Object.getOwnPropertyNames
将返回
cat1
而不是
cat2
的属性名称。创建对象的两种方法不会在
object.getOwnPropertyNames
object.keys
@Boric是的,您是正确的。我本可以将Object.getPrototypeOf(cat2)与这两种方法一起使用,而不仅仅是cat2。我不能肯定,因为我不记得了,也没有代码。我会在答案中修正它。您的意思是
.keys
不返回不可枚举的属性。@RayToal。固定的。非常感谢。