摘要:注意這里因為添加完元素之后返回的是該對象,所以可以鏈式調用結果是,但是中只會存一個模擬實現的整體結構除此之外我們還需要二個輔助方法模擬行為對迭代器對象進行遍歷操作。
更多系列文章請看
在實現之前我們可以通過阮一峰的ECMAScript 6 入門了解一下Set的基本信息
1、Set的基本語法new Set([ iterable ])
可以傳遞一個可迭代對象,它的所有元素將被添加到新的 Set中。如果不指定此參數或其值為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的構造函數
size: Set 長度
操作方法
add(value):在Set對象尾部添加一個元素。返回該Set對象。
has(value):返回一個布爾值,表示該值在Set中存在與否。
delete(value):移除Set中與這個值相等的元素,返回has(value)在這個操作前會返回的值(即如果該元素存在,返回true,否則返回false)
-clear():移除Set對象內的所有元素。沒有返回值
遍歷方法
keys():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值。
-values():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值。
entries():返回一個新的迭代器對象,該對象包含Set對象中的按插入順序排列的所有元素的值的[value, value]數組。為了使這個方法和Map對象保持相似, 每個值的鍵和值相等。
-forEach(callbackFn[, thisArg]):按照插入順序,為Set對象中的每一個值調用一次callBackFn。如果提供了thisArg參數,回調中的this會是這個參數。
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對象,所以可以鏈式調用 // NaN === NaN 結果是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、模擬實現 2.1、Set的整體結構
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、實現源碼
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`); // 循環可迭代對象,初始化 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(); } }
模擬過程中可能會有相應的錯誤,也不是和原生的實現完全一致。僅當學習之用.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102925.html
摘要:基本介紹提供了新的數據結構。初始化本身是一個構造函數,用來生成數據結構。函數可以接受一個數組或者具有接口的其他數據結構作為參數,用來初始化。返回一個布爾值,表示該值是否為的成員。清除所有成員,無返回值。 基本介紹 ES6 提供了新的數據結構 Set。 它類似于數組,但是成員的值都是唯一的,沒有重復的值。 初始化 Set 本身是一個構造函數,用來生成 Set 數據結構。 let set ...
摘要:過濾掉和簡單判斷是否是迭代器對象模擬行為對迭代器對象進行遍歷操作。看到這里你可能已經知道了,要實現的功能之一就是提供一個迭代器。原文鏈接參考迭代器和生成器系列之模擬實現一個數據結構展開語法循環 前言 es6新增了Set數據結構,它允許你存儲任何類型的唯一值,無論是原始值還是對象引用。這篇文章希望通過模擬實現一個Set來增加對它的理解。 原文鏈接 用在前面 實際工作和學習過程中,你可能也...
摘要:沒有箭頭函數沒有自己的對象,這不一定是件壞事,因為箭頭函數可以訪問外圍函數的對象那如果我們就是要訪問箭頭函數的參數呢你可以通過命名參數或者參數的形式訪問參數不能通過關鍵字調用函數有兩個內部方法和。 1、基本語法回顧 我們先來回顧下箭頭函數的基本語法。ES6 增加了箭頭函數: var f = v => v; // 等同于 var f = function (v) { return ...
摘要:的類使用熟悉的關鍵字指定類繼承的函數,并且可以通過方法訪問父類的構造函數。例如繼承一個的類繼承了,術語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內建對象繼承的實用之處是改變返回對象的類型。 和其它面向對象編程語言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態、派生、抽象、迭代、單例等,而且根據 ES6 的新特性衍...
閱讀 1829·2021-09-14 18:03
閱讀 2267·2019-08-30 15:48
閱讀 1121·2019-08-30 14:09
閱讀 507·2019-08-30 12:55
閱讀 2724·2019-08-29 11:29
閱讀 1483·2019-08-26 13:43
閱讀 2311·2019-08-26 13:30
閱讀 2369·2019-08-26 12:17