ECMAScript 之取得 Object 所有 Property 的 Key

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

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


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

查看所有标签

猜你喜欢:

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

On LISP

On LISP

Paul Graham / Prentice Hall / 09 September, 1993 / $52.00

On Lisp is a comprehensive study of advanced Lisp techniques, with bottom-up programming as the unifying theme. It gives the first complete description of macros and macro applications. The book also ......一起来看看 《On LISP》 这本书的介绍吧!

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

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具