Heim  >  Artikel  >  Web-Frontend  >  Neue Funktionen von ES6 – detaillierte Code-Einführung in Datenstrukturen vom Typ Set und WeakSet in JavaScript

Neue Funktionen von ES6 – detaillierte Code-Einführung in Datenstrukturen vom Typ Set und WeakSet in JavaScript

黄舟
黄舟Original
2017-03-07 14:15:211242Durchsuche

ES6 stellt eine neue Datenstruktur Set bereit. Das Set-Objekt ist kein Array und kann zum Speichern von Objekten oder Grundtypen aller gespeicherten Werte verwendet werden ​​sind Die einzigen , Chrome-Browser>38 und FF>13 sowie nodeJS, die Set gut unterstützen. Einige der folgenden Codes können auf die Konsole kopiert werden und direkt ausführen;

Die grundlegende Methode zum Erstellen einer Set-Instanz ist:

let set = new Set(); //或者 new Set(null);
console.log(set);

oder so:

let set = new Set([1,2,3,4,4,4,4,4]);
console.log( Array.from(set) ); //输出:[ 1, 2, 3, 4 ]

Wie Sie sehen können, wiederholt sich das oben Gesagte 4 ist in setEs wird nur eines darin gespeichert, daher kann das Set-Objekt zum Deduplizieren des Arrays verwendet werden;

Set kann auch zum Speichern von NaN und verwendet werden undefiniert. Wenn es doppelte NaNs gibt, betrachtet Set sie als NaN (eigentlich NaN!=NaN);

Das Objekt nach dem Instanz-Set hat diese Eigenschaften und Methoden :

Eigenschaften

Set.prototype
Set.prototype.size

Methoden

Set.prototype.add()
Set.prototype.clear()
Set.prototype.delete()
Set.prototype.entries()
Set.prototype.forEach( )
Set.prototype.has()
Set.prototype.values()
Set.prototype[@@iterator]()

SetTatsächlich Wir können Arrays direkt für diese Art von Datenstruktur verwenden. Das simulierte kann zwar nicht mit dem Original verglichen werden, es kann jedoch nur einige der Methoden und simulieren Attribute in der obigen Liste (es gibt auch einige Funktionen, die nicht realisiert werden können, z. B. [Symbol. species] zeigt auf sich selbst, aber so etwas wie [Symbol.species] gibt es in Chrome nicht ...)

Verwenden Sie ein Array, um einen Set-Konstruktor zu simulieren:

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<script>
    "use strict";
    class Set {
        //对_set进行去重;
        static refresh () {
            let _this = this;
            let __set = []
            this._set.forEach(function(obj) {
                if( __set.indexOf(obj) === -1 && obj!=undefined) {
                    __set.push(obj);
                }
            });
            _this._set =__set;
            this.size = _this._set.length;
        }
        constructor(arg) {
            this.size = 0;
            this[Symbol.species] = this;
            this._set = Array.isArray(arg)&&arg||[];
            Set.refresh.call(this)
        }
        add (obj) {
            this._set.push(obj);
            Set.refresh.call(this)
            return this;
        }
        clear () {
            this._set.length = 0;
            return this;
        }
        delete (obj) {
            if( this._set.indexOf(obj)!=-1 ) {
                this._set[this._set.indexOf(obj)] = undefined;
            };
            Set.refresh.call(this);
            return this;
        }
        /**
         * @desc
         * @return Entries [[],[],[],[]]
         * */
                entries () {
            let result = [];
            this.forEach(function(key, value) {
                result.push([key,value]);
            });
            return result;
        }
        has () {
            if( this._set.indexOf(obj)!=-1 ) return true;
        }
        keys () {
            return this[Symbol.iterator]();
        }
        values () {
            return this[Symbol.iterator]();
        }
        //直接使用数组的forEach方便啊;
        forEach (fn, context) {
            let _this = this;
            this._set.forEach((value) => fn.call(context||value, value, value, _this) );
        }
        //必须支持生成器的写法;
    *[Symbol.iterator] (){
        let index = 0;
        let val = undefined;
        while(index<this.size) {
        val = this._set[index];
        yield  val;
        index++;
    }
    }
    }
    var set = new Set([0,0]);
    //对Set进行基本的操作;
    set.add(1).add(2).add(3).add({1:1})
    set.delete(1);
    set.add(1);
    //使用Set的forEach方法;
    set.forEach(function(key,value,s){console.log(key,value,s,"this")},{this:"this"})
    //检测生成器是否正常运行;
    for(let s of set) {
        console.log(s)
    }
    //因为这个对象有Symbol.iterator, 所以使用扩展符也是好使的;
    console.log([...set]);
</script>
</body>
</html>

Attribute der Set-Instanz:

Größenattribut: Größe bezieht sich auf die Länge dieses Sets, das dasselbe hat Wirkung als Länge des Arrays. „
Konstruktorattribut: Dieses Attribut zeigt auf den Set-Konstruktor, und dieser Code kann implementiert werden (neues Set).constructor === Set //Ausgabe: true

Instanzmethoden festlegen:

Methode hinzufügen, Daten zum Satz hinzufügen;

<script>
    Array.from((new Set([1,2])).add(3)); // 输出:[1, 2, 3]
</script>

Methode löschen, Daten im Satz löschen; Löschen Sie die angegebenen Daten im Satz:

let set = (new Set([1,2,3,4]));
set.clear();
Array.from(set);

Entries-Methode:

let set = (new Set([1,2,3,4]));
set.delete(1);
Array.from(set); //输出:[2, 3, 4]

forEach-Methode: Der Satz forEach hat zwei Parameter, der erste Parameter ist eine Funktion und der zweite Parameter ist optional. Wenn der zweite Parameter übergeben wird, ist der Kontext der Funktion der zweite Parameter, den wir übergeben:

let set = (new Set([1,2,3,4]));
Array.from(set.entries());

Ausgabe:

<script>
let set = (new Set([1,2,3,4]));
set.forEach(function() {
    console.log(arguments);
    console.log(this)
},"1111");
</script>

has-Methode, has wird verwendet, um zu bestimmen, ob diese Menge einen angegebenen Wert hat und false oder true zurückgibt; >@@iterator()-Methode, @iterator-Methode ist der Standarditerator von set;

Tatsächlich können wir set[Symbol.iterator] überschreiben, aber es hat keine Auswirkungen auf die Schlüssel und Wertemethoden von Set;
<script>
let set = (new Set([1,2,3,4]));
console.log(set.has(1)) //输出:true;
console.log(set.has(5)) //输出:false
</script>

Gesamte DEMO:

<script>
let set = new Set([1,2,3,4]);
console.log(set.keys());
console.log(set.values());

var keys = set.keys();
for(let key of keys) {
    console.log(key);
};
</script>

Die tatsächliche Verwendung von Set:

<script>
let set = new Set([1,2,3,4]);
let setIner = set[Symbol.iterator]();
console.log(setIner.next().value) //输出:1
console.log(setIner.next().value) //输出:2
console.log(setIner.next().value) //输出:3
console.log(setIner.next().value) //输出:4
</script>
Mit set können Sie problemlos Schnittmengen und Vereinigungen durchführen:

Um die Vereinigung zu finden, können wir zwei oder mehr Lösungen angeben:

var mySet = new Set();
//往mySet里面添加数据, 1 , 5
mySet.add(1);
mySet.add(5);
mySet.add("some text");
//添加对象
var o = {a: 1, b: 2};
mySet.add(o);

mySet.has(1); // 返回:true
mySet.has(3); // 返回:false
mySet.has(5);              // 返回:true
mySet.has(Math.sqrt(25));  // 返回:true
mySet.has("Some Text".toLowerCase()); // t返回:rue
mySet.has(o); // 返回:true

mySet.size; // 4

mySet.delete(5); // 从mySet里面删除5
mySet.has(5);    // 输出:false, 5 已经被删除了

mySet.size; // 现在的长度为:3

// 通过 for...or循环获取数据;
// 输出: 1, "some text"
for (let item of mySet) console.log(item);

// 输出: 1, "some text"
for (let item of mySet.keys()) console.log(item);

// 输出: 1, "some text"
for (let item of mySet.values()) console.log(item);

// 输出: 1, "some text", 对于Set来说:key和value是一样的
for (let [key, value] of mySet.entries()) console.log(key);

// 把迭代器转化为数组的第一种方式;
var myArr = [v for (v of mySet)]; // [1, "some text"]
// 把迭代器转化为数组的第二种方式;
var myArr = Array.from(mySet); // [1, "some text"]
// 也可以用next()方法,手动去获取每一个值;
Diese Art, den Schnittpunkt zu ermitteln, ist fast dasselbe wie den Schnittpunkt von Arrays zu finden;

Der folgende Code ist kürzer, also cool. Diese Methode stammt von: http://es6.ruanyifeng.com/#docs/set-map;

Weakly referenced
var union = (setA, setB) => {
    //[...setA]这种方式目前只有babel才支持
    return new Seet([...setA,...setB]);
};
var union = (setA, setB) => {
    return new Set(Array.from(setA).concat(Array.from(setB)));
}
WeakSet

var intersect = (set1, set2) => {
    //return [x for (x of set1) if (set2.has(x))]; 这种写法完全不行嘛....
    var resultSet = new Set();
    for(let set of set1) {
        if(set2.has(set)) {
            resultSet.add(set);
        };
    };
    return resultSet;
};

WeakSet

-Objekt ist eine Sammlung von Objektwerten, und jeder Objektwert darin kann nur einmal vorkommen. WeakSet kann nur Elemente vom
var intersect = (set1, set2) => {
    return new Set([...set1].filter(x => set2.has(x)));
}
console.log(intersect(new Set([1,2,3,4]), new Set([2,3,4,5]))); //输出:Set {2,3,4}
Objekttyp

speichern, wie zum Beispiel: Objekt,

Array

, Funktion usw.; mit schwachen Referenzen WeakSet müssen Sie sich keine Sorgen über Speicherverluste machen Objekte verweisen nicht auf das Objekt, das Objekt wird automatisch vom Garbage Collection-Mechanismus recycelt. Das WeakSet-Objekt verfügt über kein Größenattribut >weakSet.add();

<script>
    console.log(new WeakSet([{},[],()=>({1:1})]));
</script>

weakSet.delete( );
  • weakSet.has();
  • Wenn das Objekt keine Referenz hat, dann ist das WeakSet-Objekt Der von nicht referenzierten Objekten belegte Speicher recycelt. Sie können die folgende Demo ausführen und sich dann nach einer Weile die Konsole ansehen (ich werde den Effekt in meinem Chrome-Browser

    10S
  • sehen):
  • weakSet

    kann zum Speichern von DOM-Knoten verwendet werden, wenn in
  • weakSet
keine weiteren Verweise auf den Knoten vorhanden sind.

Das Obige ist eine detaillierte Einführung in den Code der neuen Funktionen von ES6 – Datenstrukturen vom Typ Set und WeakSet in JavaScript. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn). )!

<script>
var ws = new WeakSet()
var obj = {}; ws.add(obj);
ws.add([])
setInterval(()=>{
    console.log(ws);
},1000)
</script>

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn