最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
當前位置: 首頁 - 科技 - 知識百科 - 正文

ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹

來源:懂視網 責編:小采 時間:2020-11-27 20:24:23
文檔

ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹

ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹:ES6提供了新的數據結構Set,Set對象不是數組, 可以用來保存對象或者基本類型, 所有保存的值都是唯一的, chrome瀏覽器>38和FF>13,以及nodeJS,對Set支持良好, 以下的一些代碼,都可以拷貝到控制臺直接運行哦;創建Set實例的基本方法為:let
推薦度:
導讀ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹:ES6提供了新的數據結構Set,Set對象不是數組, 可以用來保存對象或者基本類型, 所有保存的值都是唯一的, chrome瀏覽器>38和FF>13,以及nodeJS,對Set支持良好, 以下的一些代碼,都可以拷貝到控制臺直接運行哦;創建Set實例的基本方法為:let
ES6提供了新的數據結構Set,Set對象不是數組, 可以用來保存對象或者基本類型, 所有保存的值都是唯一的, chrome瀏覽器>38和FF>13,以及nodeJS,對Set支持良好, 以下的一些代碼,都可以拷貝到控制臺直接運行哦;

創建Set實例的基本方法為:

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

或者這樣:

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

可以看到,以上重復的4,在set里面只保存了一個, 所以Set對象可以用來給數組去重;

Set也能用來保存NaN和undefined, 如果有重復的NaN, Set會認為就一個NaN(實際上NaN!=NaN);

實例Set以后的對象擁有這些屬性和方法:

屬性

Set.prototype
Set.prototype.size

方法

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

Set這種類型的數據結構其實我們可以直接用數組模擬出來, 雖然不能和原生的比, 只能模擬以上列表的一些方法和屬性( 還有一些功能無法實現的 , Set實例的[Symbol.species]指向自己, 但是chrome中沒有[Symbol.species]這個玩意兒…. )

使用數組模擬一個Set構造器:

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

Set實例的屬性:

size屬性:size是指這個Set的長度,和數組的length效果一樣的”
constructor屬性: 這個屬性指向Set構造函數 ,這個代碼即可實現 (new Set).constructor === Set //輸出:true

Set實例的方法:

add方法,往set添加數據;

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

clear方法,把set里面的數據清空;

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

delete方法,刪除set里面的指定數據:

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

entries方法:

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

forEach方法:set的forEach有兩個參數, 第一個參數為一個函數,第二個參數是非必須的,如果傳了第二個參數, 那么該函數的上下文this就是我們傳的第二個參數:

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

輸出:

has方法, has是判斷這個set是否有指定的值, 返回false或者true;

<script>
let set = (new Set([1,2,3,4]));
console.log(set.has(1)) //
輸出:true; console.log(set.has(5)) //輸出:false </script>

keys方法和values()方法, 這兩個方法都是返回一個迭代器;

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

@@iterator()方法, @iterator方法是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>

實際上我們可以重寫set[Symbol.iterator],但是不會對set的keys和values方法產生影響;

整個DEMO:

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()方法,手動去獲取每一個值;

Set的實際用處:

利用set可以方便的進行交集和并集:

求并集, 我們可以給兩個方案或者更多:

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)));
}

這種獲取交集的方式,和數組求交集差不多;

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;
};

以下這種代碼更短,太酷了啊, 這個方法來自:http://es6.ruanyifeng.com/#docs/set-map;

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}

弱引用的WeakSet

WeakSet對象是一些對象值的集合, 并且其中的每個對象值都只能出現一次,WeakSet只能存對象類型的元素,比如:Object, Array, Function 等等;有了弱引用的WeakSet, 就不用擔心內存泄漏了,如果別的對象不引用該對象, 這個對象會被垃圾回收機制自動回收;

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

WeakSet對象的方法只有三個,而且WeakSet對象沒有size屬性;

  • weakSet.add();

  • weakSet.delete();

  • weakSet.has();

  • 如果對象不存在引用, 那么WeakSet對象會把沒有引用的對象占用的內存回收, 下面這個demo,你可以跑一下, 然后過一會兒(我的chrome瀏覽器10S就看到效果了)再看控制臺:

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

    weakSet可以用來保存DOM節點, 當節點被刪除, weakSet里面的該節點如果不存在別的引用的話, 一段時間內會被內存回收;

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹

    ES6新特性-JavaScript中Set和WeakSet類型的數據結構的代碼詳細介紹:ES6提供了新的數據結構Set,Set對象不是數組, 可以用來保存對象或者基本類型, 所有保存的值都是唯一的, chrome瀏覽器>38和FF>13,以及nodeJS,對Set支持良好, 以下的一些代碼,都可以拷貝到控制臺直接運行哦;創建Set實例的基本方法為:let
    推薦度:
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    国产精品久久久久精品…-国产精品可乐视频最新-亚洲欧美重口味在线-欧美va免费在线观看