【JS】JavaScript遍历对象的几种方法

JavaScript遍历对象的几种方法

sugar_coffee发布于 今天 06:18

对于经常使用对象的我们,在有些业务场景下需要对对象的属性进行遍历,下面我总结了几种常用的 JS 遍历对象属性的方法。

太长不看版:

JS 遍历对象的主要方法有 for...inObject.keys()Object.getOwnPropertyNames()Object.getOwnPropertySymbols()Reflect.ownKeys()

【JS】JavaScript遍历对象的几种方法

备注:可枚举:属性的 enumerable 值为 true;自身属性:自有的,不是从原型上继承来的属性。

  • 遍历对象所有的可枚举属性(自有的+继承的属性),使用 for...in
  • 遍历对象自有的所有可枚举属性(非继承属性),使用 Object.keys() 或 for...in + Objec.hasOwnProperty()
  • 获取对象所有继承属性(非自有属性),可以使用 for...in + Object.keys()
  • 遍历对象自有的所有可枚举和不可枚举属性(非继承属性),使用 Object.getOwnPropertyNames()
  • 获取对象自有的所有可枚举、不可枚举属性和继承属性,使用 for...in + Object.getOwnPropertyNames(obj) 或 for...in + Object.keys() + Object.getOwnPropertyNames(obj)

如果想了解更多详细内容,请往下看:

一、for...in

for...in 用于以任意顺序遍历对象所有的可枚举属性(包括对象自身的和继承的可枚举属性,不含 Symbol 属性)。

let obj = {

name: 'Scarlett',

age: 37,

[Symbol()]: 'Johansson'

}

for (let key in obj) {

console.log(key) // name age

}

// 在原型上添加一个可枚举属性

Object.prototype.nationality = 'America'

// 在obj对象上添加一个不可枚举属性

Object.defineProperty(obj, 'occupation', {

value: 'actress',

enumerable: false

})

for (let key in obj) {

console.log(key, obj[key])

}

/* 输出结果:包含对象自身的可枚举属性和原型上的可枚举属性

name Scarlett

age 37

nationality America

*/

想必大家对这个语法并不陌生,但在实际的业务场景中是对属性的精准使用,而不是直接这样用。

我们知道对象具有的属性可能是多来源的,可能是自身创建的,可能继承自原型,也可能继承自构造函数......其中我们可以通过 Object.hasOwnProperty()来判断这个属性是否是自有属性,该方法会过滤掉那些继承来的属性。

for...in 循环可以访问到对象具有的所有可枚举属性,而对象的不可枚举属性则是由属性的 enumerable 值决定的,比如 constructor,length 属性等都不能被 for...in 访问到。方法 Object.propertyIsEnumerable() 可以判断此对象是否包含某个属性,并且这个属性是否可枚举(通过原型继承的属性除外)。

二、for...of

for...of 是 ES6 新增的遍历方式,它为不同的数据结构提供了统一的遍历机制。任何数据结构只要实现了 Iterator 接口的,都可以被遍历。关于 Iterator 接口可以参考 这里

for...of 循环可以使用的范围包括 Array、Set 和 Map 结构、类数组对象(比如arguments 对象、DOM NodeList 对象)、字符串等。

1.类数组对象

以下是 for...of 循环字符串、arguments 对象、DOM 元素集合的例子:

// 字符串

let str = "hello";

for (let s of str) {

console.log(s); // h e l l o

}

// DOM元素集合

let domList = document.querySelectorAll("p");

for (let p of domList) {

p.classList.add("test");

}

// arguments对象

function printArgs() {

for (let arg of arguments) {

console.log(arg);

}

}

printArgs('a', 'b'); // 'a' 'b'

虽然不是所有的类数组对象都具有 Iterator 接口,但一个简便的解决方法,就是使用 Array.from() 方法将一个类似数组或可迭代对象转为一个浅拷贝的数组实例。

let arrayLike = { length: 2, 0: 'a', 1: 'b' };

// 报错 TypeError: arrayLike is not iterable

for (let key of arrayLike) {

console.log(key);

}

// 正确执行

for (let key of Array.from(arrayLike)) {

console.log(key); // 'a' 'b'

}

2.普通对象

对于普通的对象,for...of 结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用。

let obj = {

name: 'Scarlett',

age: 37

}

// 报错 TypeError: obj is not iterable

for (let key of obj) {

console.log(key);

}

// 解决:使用Object.keys()方法将对象的键名生成一个数组,然后遍历。

for (var key of Object.keys(obj)) {

console.log(key);

}

三、Object.keys()

Object.keys() ES5 新增的一个对象方法,该方法接收一个对象为参数,返回一个数组,包含该对象自有的可枚举属性(不含继承的和Symbol属性),数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

let obj = {

name: 'Scarlett',

age: 37,

[Symbol()]: 'Johansson'

}

// 在原型上添加一个可枚举属性

Object.prototype.nationality = 'America'

// 在obj对象上添加一个不可枚举属性

Object.defineProperty(obj, 'occupation', {

value: 'actress',

enumerable: false

})

// 获取对象自有的可枚举属性

Object.keys(obj).map(key => {

console.log(key); // name age

})

console.log(Object.entries(obj)); // [["name", "Scarlett"], ["age", 37]]

console.log(Object.values(obj)); // ["Scarlett", 37]

注意:该方法如果参数不是一个对象,将被强制转换为一个对象。

根据前面的方法的特点,使用 for...in 结合 Object.hasOwnProperty() 也能达到获取自身的可枚举属性或继承属性的目的。

// 得到所有可枚举属性(自有的和继承的属性)

for (let key in obj) {

// 过滤掉继承属性

if (obj.hasOwnProperty(key)) {

console.log(key);

}

}

另外:

  • Object.entries() 返回指定对象自身的可枚举属性的键值对(不含继承的和Symbol属性)数组;

  • Object.values() 返回指定对象自身的所有可枚举属性的值(不含继承的和Symbol属性)组成的数组;

这两个方法的使用范围和 Object.keys() 方法类似,这里不再详细说明。

四、Object.getOwnPropertyNames()

Object.getOwnPropertyNames() 方法接收一个对象为参数,返回该对象所有可枚举和不可枚举属性的属性名(不含Symbol属性)组成的数组。

// 接上demo

console.log(Object.getOwnPropertyNames(obj));  // ["name", "age", "occupation"]

综上,可以拓展出 for...in 结合 Object.getOwnPropertyNames() 获取对象自有的所有可枚举、不可枚举属性和继承属性。

const getAllPropertyNames = (obj) => {

let props = Object.assign([], Object.getOwnPropertyNames(obj))

// 得到所有的可枚举属性(自有的和继承的属性)

for (let key in obj) {

// 过滤自有的不可枚举属性

if (!Object.getOwnPropertyNames(obj).includes(key)) {

props.push(key)

}

}

return props;

};

getAllPropertyNames(obj); // ["name", "age", "occupation", "nationality"]

这里也可以使用 for...in + Object.keys() + Object.getOwnPropertyNames(obj) 的方法得到同样的结果,有兴趣的可以自行尝试。

五、Object.getOwnPropertySymbols()

Object.getOwnPropertySymbols() 方法返回指定对象自身所有的Symbol属性的数组。

// 接上demo

let symbolsArr = Object.getOwnPropertySymbols(obj);

for( let sym of symbolsArr){

console.log(sym, obj[sym]); // Symbol() "Johansson"

}

// 给对象添加一个不可枚举的Symbol属性

Object.defineProperties(obj, {

[Symbol('aa')]: {

value: 'localSymbol',

enumerable: false

}

})

Object.getOwnPropertySymbols(obj).map(key => {

console.log(key, obj[key]); // Symbol() "Johansson", Symbol(aa) "localSymbol"

})

六、Reflect.ownKeys()

Reflect.ownKeys() 返回指定对象自身的所有属性(包含不可枚举属性和Symbol属性)组成的数组。它的返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))

// 接上demo

Reflect.ownKeys(obj).map(key => {

console.log(key, obj[key])

})

/* 输出结果:

name Scarlett

age 37

occupation actress

Symbol() "Johansson"

*/

以上,

关于对象的更多用法,请移步 Mozilla MDN

javascript前端es6

阅读 40更新于 今天 06:19

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

sugar_coffee

189 声望

1 粉丝

0 条评论

得票时间

avatar

sugar_coffee

189 声望

1 粉丝

宣传栏

对于经常使用对象的我们,在有些业务场景下需要对对象的属性进行遍历,下面我总结了几种常用的 JS 遍历对象属性的方法。

太长不看版:

JS 遍历对象的主要方法有 for...inObject.keys()Object.getOwnPropertyNames()Object.getOwnPropertySymbols()Reflect.ownKeys()

【JS】JavaScript遍历对象的几种方法

备注:可枚举:属性的 enumerable 值为 true;自身属性:自有的,不是从原型上继承来的属性。

  • 遍历对象所有的可枚举属性(自有的+继承的属性),使用 for...in
  • 遍历对象自有的所有可枚举属性(非继承属性),使用 Object.keys() 或 for...in + Objec.hasOwnProperty()
  • 获取对象所有继承属性(非自有属性),可以使用 for...in + Object.keys()
  • 遍历对象自有的所有可枚举和不可枚举属性(非继承属性),使用 Object.getOwnPropertyNames()
  • 获取对象自有的所有可枚举、不可枚举属性和继承属性,使用 for...in + Object.getOwnPropertyNames(obj) 或 for...in + Object.keys() + Object.getOwnPropertyNames(obj)

如果想了解更多详细内容,请往下看:

一、for...in

for...in 用于以任意顺序遍历对象所有的可枚举属性(包括对象自身的和继承的可枚举属性,不含 Symbol 属性)。

let obj = {

name: 'Scarlett',

age: 37,

[Symbol()]: 'Johansson'

}

for (let key in obj) {

console.log(key) // name age

}

// 在原型上添加一个可枚举属性

Object.prototype.nationality = 'America'

// 在obj对象上添加一个不可枚举属性

Object.defineProperty(obj, 'occupation', {

value: 'actress',

enumerable: false

})

for (let key in obj) {

console.log(key, obj[key])

}

/* 输出结果:包含对象自身的可枚举属性和原型上的可枚举属性

name Scarlett

age 37

nationality America

*/

想必大家对这个语法并不陌生,但在实际的业务场景中是对属性的精准使用,而不是直接这样用。

我们知道对象具有的属性可能是多来源的,可能是自身创建的,可能继承自原型,也可能继承自构造函数......其中我们可以通过 Object.hasOwnProperty()来判断这个属性是否是自有属性,该方法会过滤掉那些继承来的属性。

for...in 循环可以访问到对象具有的所有可枚举属性,而对象的不可枚举属性则是由属性的 enumerable 值决定的,比如 constructor,length 属性等都不能被 for...in 访问到。方法 Object.propertyIsEnumerable() 可以判断此对象是否包含某个属性,并且这个属性是否可枚举(通过原型继承的属性除外)。

二、for...of

for...of 是 ES6 新增的遍历方式,它为不同的数据结构提供了统一的遍历机制。任何数据结构只要实现了 Iterator 接口的,都可以被遍历。关于 Iterator 接口可以参考 这里

for...of 循环可以使用的范围包括 Array、Set 和 Map 结构、类数组对象(比如arguments 对象、DOM NodeList 对象)、字符串等。

1.类数组对象

以下是 for...of 循环字符串、arguments 对象、DOM 元素集合的例子:

// 字符串

let str = "hello";

for (let s of str) {

console.log(s); // h e l l o

}

// DOM元素集合

let domList = document.querySelectorAll("p");

for (let p of domList) {

p.classList.add("test");

}

// arguments对象

function printArgs() {

for (let arg of arguments) {

console.log(arg);

}

}

printArgs('a', 'b'); // 'a' 'b'

虽然不是所有的类数组对象都具有 Iterator 接口,但一个简便的解决方法,就是使用 Array.from() 方法将一个类似数组或可迭代对象转为一个浅拷贝的数组实例。

let arrayLike = { length: 2, 0: 'a', 1: 'b' };

// 报错 TypeError: arrayLike is not iterable

for (let key of arrayLike) {

console.log(key);

}

// 正确执行

for (let key of Array.from(arrayLike)) {

console.log(key); // 'a' 'b'

}

2.普通对象

对于普通的对象,for...of 结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用。

let obj = {

name: 'Scarlett',

age: 37

}

// 报错 TypeError: obj is not iterable

for (let key of obj) {

console.log(key);

}

// 解决:使用Object.keys()方法将对象的键名生成一个数组,然后遍历。

for (var key of Object.keys(obj)) {

console.log(key);

}

三、Object.keys()

Object.keys() ES5 新增的一个对象方法,该方法接收一个对象为参数,返回一个数组,包含该对象自有的可枚举属性(不含继承的和Symbol属性),数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

let obj = {

name: 'Scarlett',

age: 37,

[Symbol()]: 'Johansson'

}

// 在原型上添加一个可枚举属性

Object.prototype.nationality = 'America'

// 在obj对象上添加一个不可枚举属性

Object.defineProperty(obj, 'occupation', {

value: 'actress',

enumerable: false

})

// 获取对象自有的可枚举属性

Object.keys(obj).map(key => {

console.log(key); // name age

})

console.log(Object.entries(obj)); // [["name", "Scarlett"], ["age", 37]]

console.log(Object.values(obj)); // ["Scarlett", 37]

注意:该方法如果参数不是一个对象,将被强制转换为一个对象。

根据前面的方法的特点,使用 for...in 结合 Object.hasOwnProperty() 也能达到获取自身的可枚举属性或继承属性的目的。

// 得到所有可枚举属性(自有的和继承的属性)

for (let key in obj) {

// 过滤掉继承属性

if (obj.hasOwnProperty(key)) {

console.log(key);

}

}

另外:

  • Object.entries() 返回指定对象自身的可枚举属性的键值对(不含继承的和Symbol属性)数组;

  • Object.values() 返回指定对象自身的所有可枚举属性的值(不含继承的和Symbol属性)组成的数组;

这两个方法的使用范围和 Object.keys() 方法类似,这里不再详细说明。

四、Object.getOwnPropertyNames()

Object.getOwnPropertyNames() 方法接收一个对象为参数,返回该对象所有可枚举和不可枚举属性的属性名(不含Symbol属性)组成的数组。

// 接上demo

console.log(Object.getOwnPropertyNames(obj));  // ["name", "age", "occupation"]

综上,可以拓展出 for...in 结合 Object.getOwnPropertyNames() 获取对象自有的所有可枚举、不可枚举属性和继承属性。

const getAllPropertyNames = (obj) => {

let props = Object.assign([], Object.getOwnPropertyNames(obj))

// 得到所有的可枚举属性(自有的和继承的属性)

for (let key in obj) {

// 过滤自有的不可枚举属性

if (!Object.getOwnPropertyNames(obj).includes(key)) {

props.push(key)

}

}

return props;

};

getAllPropertyNames(obj); // ["name", "age", "occupation", "nationality"]

这里也可以使用 for...in + Object.keys() + Object.getOwnPropertyNames(obj) 的方法得到同样的结果,有兴趣的可以自行尝试。

五、Object.getOwnPropertySymbols()

Object.getOwnPropertySymbols() 方法返回指定对象自身所有的Symbol属性的数组。

// 接上demo

let symbolsArr = Object.getOwnPropertySymbols(obj);

for( let sym of symbolsArr){

console.log(sym, obj[sym]); // Symbol() "Johansson"

}

// 给对象添加一个不可枚举的Symbol属性

Object.defineProperties(obj, {

[Symbol('aa')]: {

value: 'localSymbol',

enumerable: false

}

})

Object.getOwnPropertySymbols(obj).map(key => {

console.log(key, obj[key]); // Symbol() "Johansson", Symbol(aa) "localSymbol"

})

六、Reflect.ownKeys()

Reflect.ownKeys() 返回指定对象自身的所有属性(包含不可枚举属性和Symbol属性)组成的数组。它的返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))

// 接上demo

Reflect.ownKeys(obj).map(key => {

console.log(key, obj[key])

})

/* 输出结果:

name Scarlett

age 37

occupation actress

Symbol() "Johansson"

*/

以上,

关于对象的更多用法,请移步 Mozilla MDN

以上是 【JS】JavaScript遍历对象的几种方法 的全部内容, 来源链接: utcz.com/a/111575.html

回到顶部