ECMAScript 之取得 Object 所有 Property 的 Key

栏目: JavaScript · 发布时间: 7年前

内容简介:ECMAScript Object 的 Property 基本上是由 Key / Value 構成,連 Method 也是指向 Function 的 Property,我們該如何取得 Object 所有 Property 的 Key 做進一步的運用呢 ?ECMAScript 3ECMAScript 5.1

ECMAScript Object 的 Property 基本上是由 Key / Value 構成,連 Method 也是指向 Function 的 Property,我們該如何取得 Object 所有 Property 的 Key 做進一步的運用呢 ?

Version

ECMAScript 3

ECMAScript 5.1

ECMAScript 2015

Object.keys()

將 Object 所有 Enumerable Property 的 Key 以 array 傳回,但不包含 Prototype 的 Property

ECMAScript 5.1

至於什麼是 Enumerable Property 呢 ? 稍後會介紹。

var person = {
  firstName: 'Sam',
  lastName: 'Xiao',
  fullName: function() {
    return this.firstName + ' ' + this.lastName;
  }
};

Object.keys(person)
  .forEach(key => console.log(key));

// firstName
// lastName
// fullName

以 Object Literal 定義 person ,在 Object Literal 的 property 都是 enumerable,所以 Object.keys() 都能顯示。

ECMAScript 之取得 Object 所有 Property 的 Key

  1. 因為 Object.keys() 回傳為 array,因此能直接使用 forEach()
  2. Object Literal 皆為 Enumerable Property,因此所有 key 都能顯示
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return this.firstName + ' ' + this.lastName;
};

var person = new Person('Sam', 'Xiao');

Object.keys(person)
  .forEach(key => console.log(key));

// firstName
// lastName

ECMAScript 的 OOP 正統寫法,是將 method 定義在 Prototype,但 Object.keys() 無法抓到 Prototype 的 property。

ECMAScript 之取得 Object 所有 Property 的 Key

Object.keys()
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

var person = new Person('Sam', 'Xiao');

Object.keys(person)
  .forEach(key => console.log(key));

// firstName
// lastName

若使用 ECMAScript 2015 的 class 寫法, Object.keys() 也只能抓到 firstNamelastName ,別忘了 class 本質仍是 Constructor Function,其 method 也是定義在 Prototype,因此 Object.keys() 抓不到很合理。

Q : 若要也顯示 Prototype 的 Enumerable Property 呢 ?

要使用 for...in ,稍後會介紹。

Object.getOwnPropertyNames()

將 Object 所有 Property 的 Key 以 array 傳回,包含 Enumerable 與 Non Enumerable Property,但不包含 Prototype 的 Property

ECMAScript 5.1

Object Literal 的 property 都是 Enumerable,所以 Object.keys() 都能使用,但要如何產生 Non Enumerable 的 property 呢 ?

var property = {
  firstName: {
    value: 'Sam',
    writable: true,
    configurable: true,
    enumerable: true,
  },
  lastName: {
    value: 'Xiao',
    writable: true,
    configurable: true,
    enumerable: false,
  },
  fullName: {
    value: function() {
      return this.firstName + ' ' + this.lastName;
    },
    writable: true,
    configurable: true,
    enumerable: true,
  },
};

var person = Object.create({}, property);

Object.keys(person)
  .forEach(key => console.log(key));

// firstName
// fullName

若要特別建立 Non Enumerable Property,就必須使用 Object.create() ,並特別在 Property Object 設定是否為 Enumerable。

第 8 行

lastName: {
  value: 'Xiao',
  writable: true,
  configurable: true,
  enumerable: false,
},

特別設定 lastName property 的 enumerablefalse ,則 Object.keys() 將無法顯示 lastName

ECMAScript 之取得 Object 所有 Property 的 Key

  1. lastNameEnumerable 設定為 false
  2. 使用 Object.keys()
  3. 只顯示 EnumerabletruefirstNamefullName
var property = {
  firstName: {
    value: 'Sam',
    writable: true,
    configurable: true,
    enumerable: true,
  },
  lastName: {
    value: 'Xiao',
    writable: true,
    configurable: true,
    enumerable: false,
  },
  fullName: {
    value: function() {
      return this.firstName + ' ' + this.lastName;
    },
    writable: true,
    configurable: true,
    enumerable: true,
  },
};

var person = Object.create({}, property);

Object.getOwnPropertyNames(person)
  .forEach(key => console.log(key));

// firstName
// lastName
// fullName

若改用 Object.getOwnPropertyNames() ,則僅管 lastNameEnumerablefalse ,但 Object.getOwnPropertyNames() 仍然會顯示。

ECMAScript 之取得 Object 所有 Property 的 Key

  1. lastNameEnumerable 設定為 false
  2. 使用 Object.getOwnPropertyNames()
  3. 無論 Enumerabletruefalse 都會顯示
var prototype = {
  fullName: function() {
    return this.firstName + ' ' + this.lastName;
  },
};

var property = {
  firstName: {
    value: 'Sam',
    writable: true,
    configurable: true,
    enumerable: true,
  },
  lastName: {
    value: 'Xiao',
    writable: true,
    configurable: true,
    enumerable: false,
  },
};

var person = Object.create(prototype, property);

Object.getOwnPropertyNames(person)
  .forEach(key => console.log(key));

// firstName
// lastName

fullName() 移到 Prototype,而 Object Literal 都是 Enumerable Property。

但因為 Object.getOwnPropertyNames() 不會顯示 Prototype 的 property,因此只能顯示 firstNamelastName

ECMAScript 之取得 Object 所有 Property 的 Key

fullName()
Object.getOwnPropertyNames()
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

var person = new Person();

Object.getOwnPropertyNames(person)
  .forEach(key => console.log(key));

// firstName
// lastName

若使用 ECMAScript 2015 的 class 寫法, Object.getOwnPropertyNames() 也只能抓到 firstNamelastName ,別忘了 class 本質仍是 Constructor Function,其 method 也是定義在 Prototype,因此 Object.getOwnPropertyNames() 抓不到很合理。

for…in

如同 Object.keys() 將 Object 所有 Enumerable Property 的 Key 以 array 傳回,但包含 Prototype 的 Property

ECMAScript 3

我們發現無論 Object.keys()Object.getOwnPropertyNames() ,都無法顯示 Prototype 的 property,若要連 Prototype 的 property 也一起顯示,則要使用 for...in

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return this.firstName + ' ' + this.lastName;
};

var person = new Person('Sam', 'Xiao');

for(let key in person)
  console.log(key);

// firstName
// lastName
// fullName

fullName() 定義在 Prototype,之前使用 Object.keys()Object.getOwnPropertyNames() 都無法顯示,但使用 for...in 就可完全顯示了。

ECMAScript 之取得 Object 所有 Property 的 Key

fullName()
for...in
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

var person = new Person('Sam', 'Xiao');

for(let key in person)
  console.log(key);

// firstName
// lastName

for...in 搭配 ECMAScript 2015 的 class 時,卻不會顯示 fullName

理論上 classfullName() 是在 Prototype 上, for...in 應該會顯示卻沒顯示,也就是若搭配 classfor...in 相當於 Object.keys() ,結果比較令人訝異。

簡單來說,能被 Object.keys()for in 顯示的 property 就稱為 Enumerable Property,一般 Object Literal、Constructor Function 或 class 寫法的 property,都是 Enumerable Property,若要特別設定為 Non Enumerable Property,則要使用 Object.create() 建立 object

Summary

Object.keys() Object.getOwnPropertyNames() for in
Non Enumerable No Yes No
Prototype No No Yes
Object.keys()
Object.getOwnPropertyNames()
for in

Conclusion

  • 三種方式都各有其限制,要視需求選擇合適的方式
  • Object.keys()for..in 搭配 class 時,竟然結果一樣,比較出乎意外,因為篇幅限制,將令開專文討論之

Reference

MDN , Object.keys()

MDN , Object.getOwnPropertyNames()

MDN , for in


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

An Introduction to Probability Theory and Its Applications

An Introduction to Probability Theory and Its Applications

William Feller / Wiley / 1991-1-1 / USD 120.00

Major changes in this edition include the substitution of probabilistic arguments for combinatorial artifices, and the addition of new sections on branching processes, Markov chains, and the De Moivre......一起来看看 《An Introduction to Probability Theory and Its Applications》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具