5 种方法遍历对象的属性

  const s = Symbol('s');

  // 测试对象
  const test = {
    num: 0,
    str: '',
    boolean: true,
    unf: undefined,
    nul: null,
    obj: {
      name: '我是一个对象',
      id: 1,
      innerObj: {
        name: '我是对象的对象',
        id: 1.1
      }
    },
    arr: [0, 1, 2],
    date: new Date('1996/03/03'),
    reg: new RegExp(/我是一个正则/ig),
    err: new Error('我是一个错误'),
    [s]: '我的key是Symbol',
    noEnumerable: '我是手动设置的不可枚举属性',
    func() {
      console.log('我是一个函数');
    },
    get num1() {
      return this.num;
    },
    set num1(val) {
      this.num = val
    }
  };

  Object.defineProperty(test, 'noEnumerable', {enumerable: false});

  // 创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
  const testInstance =  Object.create(test);

#. 以下列出的no与yes是判断是否可拷贝列出的属性

1. for...in

继承的可枚举属性 (yes)
自身的可枚举属性 (yes)
自身的不可枚举属性 (no)
自身的Symbol属性 (no)

  for(let attr in test) {
    console.log(attr); //num、str、boolean、unf、nul、obj、arr、date、date、reg、err、func、num1
  }
  
  for(let attr in testInstance) {
    console.log(attr) //num、str、boolean、unf、nul、obj、arr、date、date、reg、err、func、num1
  }

2. Object.keys

继承的可枚举属性 (no)
自身的可枚举属性 (yes)
自身的不可枚举属性 (no)
自身的Symbol属性 (no)

  Object.keys(test); //["num", "str", "boolean", "unf", "nul", "obj", "arr", "date", "reg", "err", "func", "num1"]
  Object.keys(testInstance); //[]

3. Object.getOwnPropertyNames

继承的可枚举属性 (no)
自身的可枚举属性 (yes)
自身的不可枚举属性 (yes)
自身的Symbol属性 (no)

  Object.getOwnPropertyNames(test); //["num", "str", "boolean", "unf", "nul", "obj", "arr", "date", "reg", "err", "noEnumerable", "func", "num1"]
  Object.getOwnPropertyNames(testInstance); //[]

4. Object.getOwnPropertySymbols

继承的Symbol属性 (no)
自身的Symbol属性 (yes)

  Object.getOwnPropertySymbols(test); //[Symbol(s)]
  Object.getOwnPropertySymbols(testInstance); //[]

5. Reflect.ownKeys

继承的可枚举属性 (no)
自身的可枚举属性 (yes)
自身的不可枚举属性 (yes)
自身的Symbol属性 (yes)

  Reflect.ownKeys(test); //["num", "str", "boolean", "unf", "nul", "obj", "arr", "date", "reg", "err", "noEnumerable", "func", "num1", Symbol(s)]
  Reflect.ownKeys(testInstance); //[]

#. 以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则

首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。

猜你喜欢

转载自blog.csdn.net/Wangdanting123/article/details/85017549