遍历对象属性及确保遍历的属性顺序

对象的属性分为两种:数据属性和访问器属性,也就是是否可枚举。
对象属性分为原型属性和实例属性。原型属性是定义在对象的原型(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 循环遍历
  1. 返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例。
  2. 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
  1. for…of为ES6新增的方法,主要来遍历可迭代的对象(包括Array, Map, Set, arguments等),它主要用来获取对象的属性值,而for…in主要获取对象的属性名。
  2. for…of 不能用在对象上
const result = ['name', 'age', 'male'];
    for (const j of result) {
      console.log(j);
    }

在这里插入图片描述

此外还有一些方法可以获得对象属性,这里就不一一列举。

5. 遍历对象的顺序

这个遍历对象有个坑,首先它是一个对象,其实对象是不能遍历的,这些方法之所以能够让对象遍历,是因为他们都内置了将对象转化为数组的方法,但是,在将对象属性当作数组数值一一插入时,不是按照对象属性在对象中的排序,而是按照,【属性在对象中创建的时间】,这就带来了一些问题,关于这个要如何解决,有两个方法。

  1. 如果后台用map方法,其实也是不能够排序的,这里我们就想出一个方法,在每个属性前面加 字母+数字,如
    name -> a1_name
    然后前端在用 Object.keys(result).sort().map() 遍历,这样出来就可以控制输出顺序了。
  2. 还有一种就是前端排序了,自己想了一个方法,这样也是可以控制输出顺序
    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

参考链接:

对象属性遍历

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值