对象的属性分为两种:数据属性和访问器属性,也就是是否可枚举。
对象属性分为原型属性和实例属性。原型属性是定义在对象的原型(prototype)中的属性,而实例属性是添加的新属性。
1. Obejct.keys(obj),返回一个数组
用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组。
test = () => {
const result = {
name: '1',
age: '2',
male: '3'
};
const a = Object.keys(result);
console.log(a);
Object.keys(result).map((item) => {
console.log('key', item);
console.log('value', result[item]);
return item;
});
}
2. for … in 循环遍历
- 返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例。
- for…in主要用于遍历对象的属性,但同样也可以用来遍历数组元素。
test = () => {
const result = {
name: '1',
age: '2',
male: '3'
};
for (const i in result) {
if (Object.prototype.hasOwnProperty.call(result, i)) {
console.log(i);
}
}
}
3. Object.getOwnPropertyNames()
返回对象的所有自身属性的属性名(包括不可枚举的属性)组成的数组,但不会获取原型链上的属性。
test = () => {
const result = {
name: '1',
age: '2',
male: '3'
};
const a = Object.getOwnPropertyNames(result);
console.log(a);
}
4. for…of
- for…of为ES6新增的方法,主要来遍历可迭代的对象(包括Array, Map, Set, arguments等),它主要用来获取对象的属性值,而for…in主要获取对象的属性名。
- for…of 不能用在对象上
const result = ['name', 'age', 'male'];
for (const j of result) {
console.log(j);
}
此外还有一些方法可以获得对象属性,这里就不一一列举。
5. 遍历对象的顺序
这个遍历对象有个坑,首先它是一个对象,其实对象是不能遍历的,这些方法之所以能够让对象遍历,是因为他们都内置了将对象转化为数组的方法,但是,在将对象属性当作数组数值一一插入时,不是按照对象属性在对象中的排序,而是按照,【属性在对象中创建的时间】,这就带来了一些问题,关于这个要如何解决,有两个方法。
- 如果后台用map方法,其实也是不能够排序的,这里我们就想出一个方法,在每个属性前面加 字母+数字,如
name -> a1_name
然后前端在用 Object.keys(result).sort().map() 遍历,这样出来就可以控制输出顺序了。 - 还有一种就是前端排序了,自己想了一个方法,这样也是可以控制输出顺序
test = () => { const a = { name: '1', age: '2' }; const test1 = []; const test2 = []; const test = [ 'name', 'age', 'gender', ]; test.forEach((value) => { if (a[value]) { test1.push(value); test2.push(a[value]); } }); }
6. 使用 for …of 遍历对象
ES6 中引入了 Iterator,只有提供了 Iterator 接口的数据类型才可以使用 for-of 来循环遍历,而 Array、Set、Map、某些类数组如 arguments 等数据类型都默认提供了 Iterator 接口,所以它们可以使用 for-of 来进行遍历,而对象没有Iterator 接口,所以他不能被 for…of 遍历。
如果想让对象被遍历,那么可以借助ES6 的 Symbol.iterator 属性,只要一个数据结构有这个属性,就会被视为有 Iterator 接口
let obj = { a: 1 , b: 2, c: 3, d: 4 } ;
let newObj = Object.create(obj) ;
newObj.e = 5;
newObj.f = 6;
newObj[Symbol.iterator] = function(){
let index = 0
, self = this
, keys = Object.keys( self )
;
return {
next(){
if( index < keys.length ){
return {
value: self[keys[index++]]
, done: false
};
}
else{
return {
value: undefined
, done: true
}
}
}
};
};
可以简化成一个 Generator 函数
newObj[Symbol.iterator] = function* (){
let keys = Object.keys( this )
;
for(let i = 0, l = keys.length; i < l; i++){
yield this[keys[i]];
}
}
可以调整一下,输出 key 和 value
newObj[Symbol.iterator] = function* (){
let keys = Object.keys( this )
;
for(let i = 0, l = keys.length; i < l; i++){
yield {
key: keys[i]
, value: this[keys[i]]
};
}
}
for(let {key, value} of newObj){
console.log(key, value );
}
// e 5
// f 6
在 class 中使用 Symbol.iterator
class User{
constructor(name, age){
this.name = name;
this.age = age;
}
*[Symbol.iterator](){
let keys = Object.keys( this );
for(let i = 0, l = keys.length; i < l; i++){
yield {
key: keys[i]
, value: this[keys[i]]
};
}
}
}
let person = new User('test', 18);
for(let {key, value} of person){
console.log(key, value);
}
// name test
// age 18
参考链接: