1. 程式人生 > >5 種方法遍歷物件的屬性

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 鍵,按照加入時間升序排列。