ES 6学習(三)のSetのシミュレーションが実現しました.

5533 ワード

もっと多いシリーズの文章を見てください.
実現する前に、私達は阮一峰のECMAScript 6入門を通してSetの基本情報を知ることができます.
1、セットの基本文法
new Set([ iterable ])
新しいSetには、すべての要素が追加されます.このパラメータまたはその値が指定されていない場合、新しいnullは空です.
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例の属性と方法
属性
  • Set:constructorのアーキテクチャ関数
  • Set:size長さ
  • 操作方法
  • Set :Setオブジェクトの末尾に要素を追加する.Setオブジェクトを返します.
  • add(value):Setに存在するかどうかを示すブール値を返します.
  • has(value):Setのこの値に等しい要素を除去し、delete(value)がこの動作の前に戻ってくる値(すなわち、要素が存在する場合、trueに戻ります.そうでなければfalseに戻ります)
  • を返します.
    has(value):Setオブジェクト内のすべての要素を除去する.戻り値がありません
    巡回方法
  • clear():Setオブジェクト中の挿入順に配列されたすべての要素の値を含む新しいサブジェネレータオブジェクトを返す.
  • keys():Setオブジェクト中の挿入順に配列されたすべての要素の値を含む、新しいサブジェネレータオブジェクトを返します.
  • values():Setオブジェクト中の挿入順に配列されたすべての要素の値を含む新しいサブジェネレータオブジェクトを返します.この方法をMapオブジェクトと同様に維持するためには、各値のキーと値が等しくなります.
  • -entries():挿入順に、Setオブジェクトのそれぞれの値のためにコールバックFnを呼び出す.このパラメータは、thisArgパラメータが提供されると、このパラメータになります.
    
    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、セットの全体構造
    
    class Set {
    
      constructor (iterable) {}
    
      get size () {}
    
      has () {}
    
      add () {}
    
      delete () {}  
    
      clear () {}
    
      forEach () {}
    
      keys () {}
    
      values () {}  
    
      entries () {}
    
      [ Symbol.iterator ] () {}
    }
    この他にも、2つの補助方法1、forEach(callbackFn[, thisArg])が必要であり、アナログforOfの挙動は、ローズマリーオブジェクトを巡回操作する.
    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、for ofディショナー、より多くのディショナー情報はIteratorを見てください.私たちはこの中にローズマリーを使うのは、私たちのセットのIteratorなどを巡回できるようにするためです.
    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();
        }
    }
    シミュレーション中には対応するエラーがあるかもしれません.オリジナルの実現と完全に一致していません.勉強に使うだけです