1. 程式人生 > >ES6-物件的擴充套件-屬性的可列舉性和遍歷

ES6-物件的擴充套件-屬性的可列舉性和遍歷

可列舉

物件的每一個屬性都有一個描述物件,用來控制該屬性的行為。Object.getOwnpropertyDescriptor 方法可以獲取該屬性的描述物件。

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述物件的 enumerable 屬性,稱為“可沒舉性”,如果該屬性為 false,就表示某些操作會忽略當前屬性。

目前,有四個操作會忽略 enumerable 為 false 的屬性。

  • for...in 迴圈:只遍歷物件自身的和繼承的可列舉的屬性。
  • Object.keys():返回物件自身的所有可列舉的屬性和鍵名。
  • JSON.stringify():只序列化物件自身的可列舉的屬性。
  • Object.assign():忽略 enumerable 為 false 的屬性,只拷貝物件自身的可列舉的屬性。
這四個操作之中,前三個是 ES5 就有的,最後一個 Object.assign() 是ES6 新增的,其中,只有 for...in 會返回繼承的屬性,其他三個方法都會忽略繼承的屬性,只處理物件自身的屬性。實際上,引入“可列舉”(enumerable)這個概念的最初目的,就是讓某些屬性可以規避掉 for...in 操作,不然所有內部屬性都會被遍歷到。比如,物件原型的 toString 方法,以及陣列的 length 屬性,就通過“可列舉性”,從而避免被 for...in 遍歷到。
Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
// false

Object.getOwnPropertyDescriptor([], 'length').enumerable
// false
上面程式碼中,toString 和 length 屬性的 enumerable 都是 false,因此 for...in 不會遍歷到這兩個繼承自原型的屬性。

另外,ES6 規定,所有 Class 的原型的方法都是不可列舉的。

Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, 'foo').enumerable
// false
總的來說,操作中引入繼承的屬性會讓問題複雜化,大多數時候,我們只關心物件自身的屬性。所以,儘量不要用 for...in 迴圈,而用 Object.key() 代替。

屬性的遍歷

ES6 一共有5種方法可以遍歷物件的屬性。

1)for...in

for...in 迴圈遍歷物件自身的和繼承的可列舉屬性(不含 Symbol 屬性)。

2)Object.keys(obj)

Object.keys 返回一個數組,包括物件自身的(不含繼承的)所有可列舉屬性(不含 Symbol 屬性)的鍵名。

3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames 返回一個數組,包含物件自身的所有屬性(不含 Symbol 屬性,但是包括不可列舉屬性)的鍵名。

4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols 返回一個數組,包含物件自身的所有 Symbol 屬性的鍵名。

5)Reflect.ownKeys(obj)

Reflect.ownKeys 返回一個數組,包含物件自身的所有鍵名,不管鍵名是 Symbol 或字串,也不管是否可列舉。

以上的5種方法遍歷物件的鍵名,都遵守統一的屬性遍歷的次序規則。

  • 首先遍歷所有數值鍵,按照數值升序排列。
  • 其次遍歷所有字元鍵,按照加入時間升序排列。
  • 最後遍歷所有 Symbol 鍵按照加入時間升序排列。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]
上面程式碼中,Reflect.ownKeys 方法返回一個數組,包含了引數物件的所有屬性。這個陣列的屬性次序是這樣的,首先是數值屬性2和10,其次是字串屬性b和a,最後是 Symbol 屬性。

相關推薦

ES6-物件擴充套件-屬性列舉

可列舉 物件的每一個屬性都有一個描述物件,用來控制該屬性的行為。Object.getOwnpropertyDescriptor 方法可以獲取該屬性的描述物件。 let obj = { foo: 123 }; Object.getOwnPropertyDescriptor(

JavaScriptES6物件屬性列舉詳解

目錄 可列舉性 屬性的遍歷 可列舉性 物件的每個屬性都有一個描述物件,用來控制該屬性的行為,Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述物件。描述物件的enumerable屬性,稱為可列舉性,如果為true,為可列舉的,如

JS中物件屬性列舉

在JS中,物件的屬性分為可列舉和不可列舉,它是由屬性的enumerable值決定的,true為可列舉,false為不可列舉 JS中預定義的原型屬性一般是不可列舉的,而自己定義的屬性一般可列舉 可以通過propertyIsEnumerable方法判斷該屬性是否可列舉 屬性的列

js物件中什麼是列舉(enumerable)?

概念 可列舉性(enumerable)用來控制所描述的屬性,是否將被包括在for...in迴圈之中。具體來說,如果一個屬性的enumerable為false,下面三個操作不會取到該屬性。 * for..in迴圈 * Object.keys方法 * JSON.stringif

javascript中面向物件物件屬性,原型鏈一些擴充套件知識總結

面向物件和麵向物件程式設計 面向物件 就是找個工具,幫我完成一項工作,物件就像一個工具一樣,每個工具都可以幫我們實現某個功能,比如汽車可以實現運輸,我們只需要學會如何去開動汽車,而不需要知道汽車

JS 物件屬性"列舉"

物件屬性可列舉,表示該屬性的值不可修改,可認為該屬性是常量。 如何定義不可列舉的屬性? var obj = {name: 'jack', age:23} Object.defineProperty(obj, 'id', {value : '123', enumerable

js物件列舉

引言 說到列舉,可能很多人都會想到列舉型別,但在javascript物件中有一個屬性為可列舉性,他是什麼呢? 概念 可列舉性(enumerable)用來控制所描述的屬性,是否將被包括在for…in迴圈之中。具體來說,如果一個屬性的enumerable為false,下面三個操作不會取到該屬性。 for…in迴

C++的移植跨平臺開發

file volatil rec 遍歷 程序包 arc scu 千萬 之前 概述   今天聊聊C++的可移植性問題。如果你平時使用C++進行開發,並且你對C++的可移植性問題不是非常清楚,那麽我建議你看看這個系列。即使你目前沒有跨平臺開發的需要,了解可移植性方面的知識對你還

CLR via C#學習筆記-第十二章-驗證約束

12.8 可驗證性和約束 where關鍵字 編譯器和CLR支援稱為約束的機制,可通過它使泛型變得真正有用。 約束的作用限制能指定成泛型實參的型別數量,通過限制類型的數量,可以對那些型別執行更多操作: public static T Min<T>(T o1,T o2) whe

es6 函式擴充套件,引數作用域箭頭函式

函式的擴充套件 函式引數的預設值 基本用法 ES6 之前,不能直接為函式的引數指定預設值,只能採用變通的方法。 function log(x, y = 'World') { console.log(x, y); } log('Hello

es6 物件擴充套件運算子 res運算子

當我們對引數的個數不確定時,可以用物件拓展運算子 funtion lala(...arg){   console.log(arg[0]); 1    console.log(arg[1]); 2   console.log(arg[2]); 3   console.log(arg[3]);

談面向物件程式設計的替代

面向物件程式設計是基於”事物屬性和方法有共性”的前提下才能最大化發揮其效用的。 如果一個系統中有共性的類不多,無法/沒必要進行抽象,那就不適合使用這一程式設計模型。因為類例項化需要大量運算和記憶體。此時,使用面向過程的語言更合適。面向過程語言中所有方法都是靜態

類的三種繼承方式訪問友元函式.cpp

/*類的三種繼承方式可訪問性和友元函式 */# include <iostream> using namespace std;class A{        friend int get(const A& a);//宣告該函式為A的友元函式,使之可以在外部訪問A,友元函式也可以繼承publ

ES6物件擴充套件

今天來總結一下es6的物件擴充套件,最近一直在看es6, 感覺es6真的很好用,不過也看到過網上一些反面語言,可能因人而異,es6 的發展前景讓我們拭目以待。 一、物件屬性和方法 1.簡寫 // 屬性簡寫 var a = "first"; var

判斷物件存活:分析演算法

判斷物件存活,常用的方式是引用計數器:每當物件被一個地方引用,計數器便+1;當引用失效時,計數器-1。當物件的計數器為0時,該物件便是一個不被使用的物件,即“死亡”。引用計數器實現簡單,效率高。然而難以解決物件之間相互迴圈引用的問題(兩個失效物件相互儲存了對方的指標)。故JV

新增json物件屬性 普通js物件屬性

1. 遍歷 json 物件的屬性 //定義json物件var person= {name: 'zhangsan',pass: '123', fn: function(){ alert(this.name+"的密碼="+this.pass); }}//遍歷person屬性包

BPF的移植CO-RE (Compile Once – Run Everywhere)

## BPF的可移植性和CO-RE (Compile Once – Run Everywhere) 在上一篇[文章](https://www.cnblogs.com/charlieroro/p/14140343.html)中介紹了提高socket效能的幾個socket選項,其中給出了幾個源於核心原始碼樹中的

JavaScript創建對象的兩種方法對象的屬性

方法 style all pin on() col 兩種 ner clas 創建新對象有兩種不同的方法: 定義並創建對象的實例 使用函數來定義對象,然後創建新的對象實例 1.定義並創建對象的實例 var person=new Object(); person.firs

JavaScript物件4種方法陣列的3種方式 程式碼

//遍歷物件 4種方法 //Object.keys(obj).forEach() console.log("keys...遍歷</br>") var obj1 = { '0': 'a', '1': 'b', '2': 'c' }; Object.key