js对象属性枚举顺序

发布于:2025-04-19 ⋅ 阅读:(29) ⋅ 点赞:(0)

前言:

获取对象的可枚举属性有很多的方法:例如for in循环,Object.keys(),Object.getOwnPropertyNames(),Object.getOwnPropertySymbols()以及Object.assign(),他们在属性枚举方面有很大的区别,你了解多少呢?

枚举顺序不定:

for-in循环和Object.keys():

这两种方式枚举属性的顺序是不确定的,取决于javaScript引擎,可能因浏览器而异。

区别:

  • for-in循环会遍历对象所有的可枚举属性(不包括Symbol),包括对象自身的和对象原型上的。
  • Object.keys()仅会遍历对象自身的所有可枚举属性(不包括Symbol),而不会遍历对象原型。
const obj = { a: 1, b: 2 };
Object.prototype.c = 3; // 添加到原型链上

for (const key in obj) {
  console.log(key, obj[key]);
}
// 输出:
// a 1
// b 2
// c 3 (包括原型链上的属性)

// 如果只想遍历对象自身的属性:
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}
// 输出:
// a 1
// b 2
const obj = { a: 1, b: 2 };
Object.prototype.c = 3; // 添加到原型链上

const keys = Object.keys(obj);
console.log(keys); 
// 输出: ['a', 'b'] (只包含对象自身的属性)

keys.forEach(key => {
  console.log(key, obj[key]);
});
// 输出:
// a 1
// b 2

枚举顺序确定:

Object.getOwnPropertyNames(),Object.getOwnPropertySymbols()以及Object.assign():

三者的遍历顺序是确定的,首先升序遍历数字类型的属性,然后按照插入顺序遍历字符串和符号类型的属性。举个例子,以Object.getOwnPropertyNames()为例:

let key='key'
let obj= {
  1:'haha',
  [Symbol('m')]:'Symbol_m',
  3:'jjjj',
  "second":'dier',
  "first":'diyi',
  [key]:'key_value'
}

obj.__proto__.name='objName'

console.log(Object.getOwnPropertyNames(obj))

注意,返回的数组中,所有元素都变成字符串格式。

区别:

Object.getOwnPropertyNames(obj)
返回对象自身的所有属性(包括不可枚举属性,但不包括 Symbol 属性)的键名数组。

const obj = { a: 1, b: 2 };
Object.defineProperty(obj, 'c', { value: 3, enumerable: false });

console.log(Object.getOwnPropertyNames(obj)); 
// 输出: ['a', 'b', 'c'] (包括不可枚举属性)

Object.getOwnPropertySymbols(obj):
返回一个由指定对象自身所有 Symbol 类型的属性键名组成的数组。

const obj = {
  a: 1,
  b: 2
};
const sym1 = Symbol('c');
const sym2 = Symbol('d');
obj[sym1] = 3;
obj[sym2] = 4;

console.log(Object.getOwnPropertySymbols(obj)); 
// 输出: [Symbol(c), Symbol(d)]

Object.assign(target, ...sources):
将一个或多个源对象的所有可枚举自身属性复制到目标对象中,并返回目标对象。

const target = { a: 1, b: 2 };
const source1 = { b: 3, c: 4 };
const source2 = { d: 5 };

const result = Object.assign(target, source1, source2);

console.log(result); 
// 输出: { a: 1, b: 3, c: 4, d: 5 }
console.log(target); 
// 输出: { a: 1, b: 3, c: 4, d: 5 } (目标对象被修改)


网站公告

今日签到

点亮在社区的每一天
去签到