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


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

查看所有标签

猜你喜欢:

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

Introduction to Computation and Programming Using Python

Introduction to Computation and Programming Using Python

John V. Guttag / The MIT Press / 2013-7 / USD 25.00

This book introduces students with little or no prior programming experience to the art of computational problem solving using Python and various Python libraries, including PyLab. It provides student......一起来看看 《Introduction to Computation and Programming Using Python》 这本书的介绍吧!

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

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试