Object.getOwnPropertyNames()

Object.getOwnPropertyNames() 静态方法返回一个数组,其包含给定对象中所有自有属性(包括不可枚举属性,但不包括使用 symbol 值作为名称的属性)。

尝试一下

语法

js
Object.getOwnPropertyNames(obj)

参数

obj

一个对象,其自有的可枚举和不可枚举属性的名称被返回。

返回值

在给定对象上找到的自有属性对应的字符串数组。

描述

Object.getOwnPropertyNames() 返回一个数组,其元素是与给定对象 obj 直接关联的可枚举和不可枚举属性对应的字符串。数组中可枚举属性的顺序与使用 for...in 循环(或 Object.keys())遍历对象属性时所暴露的顺序一致。对象的非负整数键(包括可枚举和不可枚举的)首先按升序添加到数组中,然后是按插入顺序排列的字符串键。

在 ES5 中,如果该方法的参数不是一个对象(而是基本类型值),则会导致 TypeError。在 ES2015 中,非对象参数会被强制转换为对象。

js
Object.getOwnPropertyNames("foo");
// TypeError: "foo" is not an object (ES5 code)

Object.getOwnPropertyNames("foo");
// ["0", "1", "2", "length"]  (ES2015 code)

示例

使用 Object.getOwnPropertyNames()

js
const arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort());
// ["0", "1", "2", "length"]

// 类数组对象
const obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.getOwnPropertyNames(obj).sort());
// ["0", "1", "2"]

Object.getOwnPropertyNames(obj).forEach((val, idx, array) => {
  console.log(`${val} -> ${obj[val]}`);
});
// 0 -> a
// 1 -> b
// 2 -> c

// 不可枚举属性
const myObj = Object.create(
  {},
  {
    getFoo: {
      value() {
        return this.foo;
      },
      enumerable: false,
    },
  },
);
myObj.foo = 1;

console.log(Object.getOwnPropertyNames(myObj).sort()); // ["foo", "getFoo"]

如果你只想获取可枚举属性,请参见 Object.keys() 或使用 for...in 循环(请注意,这也将返回对象原型链中找到的可枚举属性,除非使用 hasOwn() 过滤)。

原型链上的属性不会被列出:

js
function ParentClass() {}
ParentClass.prototype.inheritedMethod = function () {};

function ChildClass() {
  this.prop = 5;
  this.method = function () {};
}
ChildClass.prototype = new ParentClass();
ChildClass.prototype.prototypeMethod = function () {};

console.log(Object.getOwnPropertyNames(new ChildClass()));
// ["prop", "method"]

只获取不可枚举的属性

这个方法使用 Array.prototype.filter() 函数从所有键(使用 Object.getOwnPropertyNames() 获得)的列表中过滤可枚举键(使用 Object.keys() 获得),从而仅以不可枚举键作为输出。

js
const target = myObject;
const enumAndNonenum = Object.getOwnPropertyNames(target);
const enumOnly = new Set(Object.keys(target));
const nonenumOnly = enumAndNonenum.filter((key) => !enumOnly.has(key));

console.log(nonenumOnly);

规范

Specification
ECMAScript Language Specification
# sec-object.getownpropertynames

浏览器兼容性

BCD tables only load in the browser

参见