摘要:注意這里因為添加完元素之后返回的是該對象,所以可以鏈式調(diào)用結(jié)果是,但是中只會存一個模擬實現(xiàn)的整體結(jié)構(gòu)除此之外我們還需要二個輔助方法模擬行為對迭代器對象進行遍歷操作。
更多系列文章請看
在實現(xiàn)之前我們可以通過阮一峰的ECMAScript 6 入門了解一下Set的基本信息
1、Set的基本語法new Set([ iterable ])
可以傳遞一個可迭代對象,它的所有元素將被添加到新的 Set中。如果不指定此參數(shù)或其值為null,則新的 Set為空。
let s = new Set([ 1, 2, 3 ]) // Set(3) {1, 2, 3} let s2 = new Set() // Set(0) {} let s3 = new Set(null /* or undefined */) // Set(0) {}1.1 實例屬性和方法
屬性
constructor: Set的構(gòu)造函數(shù)
size: Set 長度
操作方法
add(value):在Set對象尾部添加一個元素。返回該Set對象。
has(value):返回一個布爾值,表示該值在Set中存在與否。
delete(value):移除Set中與這個值相等的元素,返回has(value)在這個操作前會返回的值(即如果該元素存在,返回true,否則返回false)
-clear():移除Set對象內(nèi)的所有元素。沒有返回值
遍歷方法
keys():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值。
-values():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值。
entries():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值的[value, value]數(shù)組。為了使這個方法和Map對象保持相似, 每個值的鍵和值相等。
-forEach(callbackFn[, thisArg]):按照插入順序,為Set對象中的每一個值調(diào)用一次callBackFn。如果提供了thisArg參數(shù),回調(diào)中的this會是這個參數(shù)。
let s = new Set() s.add(1) // Set(1) {1} .add(2) // Set(2) {1, 2} .add(NaN) // Set(2) {1, 2, NaN} .add(NaN) // Set(2) {1, 2, NaN} // 注意這里因為添加完元素之后返回的是該Set對象,所以可以鏈式調(diào)用 // NaN === NaN 結(jié)果是false,但是Set中只會存一個NaN s.has(1) // true s.has(NaN) // true s.size // 3 s.delete(1) s.has(1) // false s.size // 2 s.clear() s // Set(0) {} let s2 = new Set([ "s", "e", "t" ]) s2 // SetIterator {"s", "e", "t"} s2.keys() // SetIterator {"s", "e", "t"} s2.values() // SetIterator {"s", "e", "t"} s2.entries() // SetIterator {"s", "e", "t"} // log [ ...s2 ] // ["s", "e", "t"] [ ...s2.keys() ] // ["s", "e", "t"] [ ...s2.values() ] // ["s", "e", "t"] [ ...s2.entries() ] // [["s", "s"], ["e", "e"], ["t", "t"]] s2.forEach(function (value, key, set) { console.log(value, key, set, this) }) // s s Set(3) {"s", "e", "t"} Window // e e Set(3) {"s", "e", "t"} Window // t t Set(3) {"s", "e", "t"} Window s2.forEach(function () { console.log(this) }, { name: "qianlongo" }) // {name: "qianlongo"} // {name: "qianlongo"} // {name: "qianlongo"} for (let value of s2) { console.log(value) } // s // e // t for (let value of s2.entries()) { console.log(value) } // ["s", "s"] // ["e", "e"] // ["t", "t"]2、模擬實現(xiàn) 2.1、Set的整體結(jié)構(gòu)
class Set { constructor (iterable) {} get size () {} has () {} add () {} delete () {} clear () {} forEach () {} keys () {} values () {} entries () {} [ Symbol.iterator ] () {} }
除此之外我們還需要二個輔助方法
1、forOf,模擬for of行為, 對迭代器對象進行遍歷操作。
const forOf = (iterable, callback, ctx) => { let result iterable = iterable[ Symbol.iterator ]() result = iterable.next() while (!result.done) { callback.call(ctx, result.value) result = iterable.next() } }
2、Iterator迭代器,更多迭代器信息請看Iterator,我們這里面用迭代器是為了讓我們的set的values()等可進行遍歷。
class Iterator { constructor (arrayLike, iteratee = (value) => value) { this.value = Array.from(arrayLike) this.nextIndex = 0 this.len = this.value.length this.iteratee = iteratee } next () { let done = this.nextIndex >= this.len let value = done ? undefined : this.iteratee(this.value[ this.nextIndex++ ]) return { done, value } } [ Symbol.iterator ] () { return this } }2.3、實現(xiàn)源碼
class Set { constructor(iterable){ this.value = []; if(!this instanceof Set) throw new Error("Constructor Set requires "new""); if(isDef(iterable)) { if(typeof iterable[ Symbol.iterator ] !== "function") new Error(`${iterable} is not iterable`); // 循環(huán)可迭代對象,初始化 forOf(iterable, value => this.add(value)); } } get size(){ return this.value.length; } has(val) { return this.value.includes(val); // [ NaN ].includes(NaN)會返回true,正好Set也只能存一個NaN } add(val) { if(!this.has(val)) { this.value.push(val); } return this; } delete(val) { const index = this.value.indexOf(val); if (index > -1) { this.value.splice(index, 1); return true; } return false; } clear() { this.value.length = 0; } forEach(cb, arg) { forOf(this.values(), val => { cb.call(arg, val, val, this); }) } keys() { return new Iterator(this.value); } values() { return this.keys(); } entries() { return new Iterator(this.value, (value) => [ value, value ]) } [Symbol.iterable]() { return this.values(); } }
模擬過程中可能會有相應(yīng)的錯誤,也不是和原生的實現(xiàn)完全一致。僅當(dāng)學(xué)習(xí)之用.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102925.html
摘要:基本介紹提供了新的數(shù)據(jù)結(jié)構(gòu)。初始化本身是一個構(gòu)造函數(shù),用來生成數(shù)據(jù)結(jié)構(gòu)。函數(shù)可以接受一個數(shù)組或者具有接口的其他數(shù)據(jù)結(jié)構(gòu)作為參數(shù),用來初始化。返回一個布爾值,表示該值是否為的成員。清除所有成員,無返回值。 基本介紹 ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set。 它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。 初始化 Set 本身是一個構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。 let set ...
摘要:過濾掉和簡單判斷是否是迭代器對象模擬行為對迭代器對象進行遍歷操作。看到這里你可能已經(jīng)知道了,要實現(xiàn)的功能之一就是提供一個迭代器。原文鏈接參考迭代器和生成器系列之模擬實現(xiàn)一個數(shù)據(jù)結(jié)構(gòu)展開語法循環(huán) 前言 es6新增了Set數(shù)據(jù)結(jié)構(gòu),它允許你存儲任何類型的唯一值,無論是原始值還是對象引用。這篇文章希望通過模擬實現(xiàn)一個Set來增加對它的理解。 原文鏈接 用在前面 實際工作和學(xué)習(xí)過程中,你可能也...
摘要:沒有箭頭函數(shù)沒有自己的對象,這不一定是件壞事,因為箭頭函數(shù)可以訪問外圍函數(shù)的對象那如果我們就是要訪問箭頭函數(shù)的參數(shù)呢你可以通過命名參數(shù)或者參數(shù)的形式訪問參數(shù)不能通過關(guān)鍵字調(diào)用函數(shù)有兩個內(nèi)部方法和。 1、基本語法回顧 我們先來回顧下箭頭函數(shù)的基本語法。ES6 增加了箭頭函數(shù): var f = v => v; // 等同于 var f = function (v) { return ...
摘要:的類使用熟悉的關(guān)鍵字指定類繼承的函數(shù),并且可以通過方法訪問父類的構(gòu)造函數(shù)。例如繼承一個的類繼承了,術(shù)語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內(nèi)建對象繼承的實用之處是改變返回對象的類型。 和其它面向?qū)ο缶幊陶Z言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態(tài)、派生、抽象、迭代、單例等,而且根據(jù) ES6 的新特性衍...
閱讀 1839·2021-09-14 18:03
閱讀 2274·2019-08-30 15:48
閱讀 1129·2019-08-30 14:09
閱讀 515·2019-08-30 12:55
閱讀 2735·2019-08-29 11:29
閱讀 1494·2019-08-26 13:43
閱讀 2318·2019-08-26 13:30
閱讀 2376·2019-08-26 12:17