關於Object類型的建立和底層存儲原理我在另外一篇文章有說明: JavaScript 對象屬性底層原理javascript
咱們知道了大多數狀況下Object底層都是Hash結構,咱們再看看V8中從Object派生的繼承圖html
數組是一種類列表對象,能夠存儲重複的對象,只能用整數做爲數組元素的索引。
在V8中數組繼承於Object,數據結構依然是Hash表。java
//An instance of the built-in array constructor (ECMA-262, 15.4.2). //Definition at line 3562 of file v8.h class V8_EXPORT Array : public Object { public: uint32_t Length() const; /** * Creates a JavaScript array with the given length. If the length * is negative the returned array will have length 0. */ static Local<Array> New(Isolate* isolate, int length = 0); V8_INLINE static Array* Cast(Value* obj); private: Array(); static void CheckCast(Value* obj); };
Map對象保存鍵值對,Key能夠是任何值(對象或原始值),Value也能夠是任何值。node
根據ECMA6-262的定義c++
Map object must be implemented using either hash tables or other mechanisms that, on average, provide access times
that are sublinear on the number of elements in the collection.
Map能夠是hash表結構或相等訪問時間的結構.算法
根據如下定義,在V8中Map繼承於Object,數據結構依然是Hash表。數組
//An instance of the built-in Map constructor (ECMA-262, 6th Edition, 23.1.1). class V8_EXPORT Map : public Object { public: size_t Size() const; void Clear(); V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,Local<Value> key); V8_WARN_UNUSED_RESULT MaybeLocal<Map> Set(Local<Context> context,Local<Value> key,Local<Value> value); V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,Local<Value> key); V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,Local<Value> key); /** * Returns an array of length Size() * 2, where index N is the Nth key and * index N + 1 is the Nth value. */ Local<Array> AsArray() const; /** * Creates a new empty Map. */ static Local<Map> New(Isolate* isolate); V8_INLINE static Map* Cast(Value* obj); private: Map(); static void CheckCast(Value* obj); };
都容許你按鍵存取一個值、刪除鍵、檢測一個鍵是否綁定了值數據結構
Set對象容許你存儲任何類型的惟一值,不管是原始值或者是對象引用。ide
根據ECMA6-262的定義函數
Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times
that are sublinear on the number of elements in the collection.
Distinct values are discriminated using the SameValueZero comparison algorithm.
根據如下定義,在V8中Set繼承於Object,數據結構依然是Hash表。
//An instance of the built-in Set constructor (ECMA-262, 6th Edition, 23.2.1). class V8_EXPORT Set : public Object { public: size_t Size() const; void Clear(); V8_WARN_UNUSED_RESULT MaybeLocal<Set> Add(Local<Context> context,Local<Value> key); V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,Local<Value> key); V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,Local<Value> key); /** * Returns an array of the keys in this Set. */ Local<Array> AsArray() const; /** * Creates a new empty Set. */ static Local<Set> New(Isolate* isolate); V8_INLINE static Set* Cast(Value* obj); private: Set(); static void CheckCast(Value* obj); };
WeakMap 對象是一組鍵/值對的集合,其中的鍵是弱引用的。其鍵必須是對象,而值能夠是任意的。
與Map相比區別:
它和 Set 對象的區別有兩點:
遍歷對象的可枚舉(enumerable爲true,非Symbol)屬性,以及對象從其構造函數原型中繼承的屬性。
原理:首先枚舉當前對象的enumerable爲true的全部屬性,而後枚舉從原型鏈中構造函數原型中繼承的屬性(更接近原型鏈中對象的屬性覆蓋原型屬性)。
ES 5標準,設計目的用於遍歷key
注:使用for in循環數組會有以下缺陷
//函數和實例的遍歷 function F0(){ this.a = "1"; } F0.b = "2"; for(var k in F0){ console.log(k);//b } var fi0=new F0(); for(var k in fi0){ console.log(k);//a } //函數繼承的遍歷 function F1(){ this.a = "a"; this.c = "F1"; } function F2(){ this.b = "b"; this.c = "F2" } F2.prototype=new F1(); var fi2 = new F2(); for(var k in fi2){ console.log(k+":"+fi2[k]);//b:b,c:F2,a:a } //數組遍歷 var ar1 = [1,2,3]; ar1.a = "a"; for(var k in ar1){ console.log(k);//0,1,2,a }
檢查對象是否具備Symbol.iterator屬性,若是存在,就調用該屬性返回的遍歷器方法。以上的集合都已經內置了該屬性,全部可使用For of遍歷。
ES 6標準,遍歷value
與for in相比,有以下區別
var ar2 = [1,2,3] ar2.length = 5; ar2.push(4); for (var k in ar2) { console.log(ar2[k]); //1,2,3,4 } for (var v of ar2) { console.log(v); //1,2,3,undefined,undefined,4 }
Refers:
http://www.ecma-international.org/publications/standards/Ecma-262.htm
https://v8docs.nodesource.com/node-10.6/annotated.html