ECMAScript 之取得 Object 的 Property Key

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

内容简介: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


以上所述就是小编给大家介绍的《ECMAScript 之取得 Object 的 Property Key》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

数据资本时代

数据资本时代

Viktor Mayer-Schnberger / 李晓霞、周涛 / 中信出版集团股份有限公司 / 2018-11-1 / CNY 58.00

【编辑推荐】 大数据除了能对我们的生活、工作、思维产生重大变革外,还能够做什么?畅销书《大数据时代》作者舍恩伯格在新书《数据资本时代》中,展示了大数据将如何从根本上改变经济——这并不是因为数据是一种新型石油,而是因为数据是一种新型润滑脂,它将给市场带来巨大能量,给公司带来巨大压力,使金融资本的作用大大削弱。赢家是市场,而并非资本。 这本书在当下国内出版,可以说恰逢其时。时下,中国经济正......一起来看看 《数据资本时代》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具