Object.getOwnPropertyNames vs Object.keys

kam*_*lkp 195 javascript

javascript Object.getOwnPropertyNamesObject.keysjavascript有什么区别?还有一些例子值得赞赏.

dfs*_*fsq 261

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

它很容易测试:

var a = {};
Object.defineProperties(a, {
    one: {enumerable: true, value: 'one'},
    two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
Run Code Online (Sandbox Code Playgroud)

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

a.test = 21;
Run Code Online (Sandbox Code Playgroud)

然后这样的属性自动变为可枚举,并且两个方法都产生相同的数组.

  • 特别是,数组对象的`length`属性是不可枚举的,所以它不会出现在`Object.keys`中. (22认同)
  • @TheQodesmith的结果是`Object.getOwnPropertyNames(anyArray)`包括`length` (7认同)
  • @Barmar对象的`length`属性在原型上,而不是对象本身,因此`Object.keys`和`Object.getOwnPropertyNames`都不会列出它. (6认同)
  • 我纠正了!`Object.getOwnPropertyNames(anyArray)`确实在返回的数组中包含`length`! (4认同)

man*_*nas 18

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

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


h3d*_*ndi 5

创建对象时的文字符号与构造函数。这是让我着迷的东西。

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在我的例子中,foo如果我给它 cat2 类型的对象,这个函数就不起作用。

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