关于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