天天看點

ES6-Array

1 /*
  2              * 數組解構指派:
  3              * ES6允許按照一定模式,從數組和對象中提取值,對變量進行指派,這種被稱為解構。
  4              * 示例如下:
  5              */
  6             var [a,b,c] = [1,2,3];
  7             console.log(a); //可以直接使用。
  8             //本質上,這種寫法屬于模式比對,隻要等号兩邊的模式相同,左邊的變量就會被賦予對應的值。
  9             //如果解構不成功,變量的值就等于undefined
 10             var [foo] = [];
 11             console.log(foo);
 12             var [bar,hoo] = [1];
 13             console.log(hoo);
 14                //上邊這兩種都屬于解構不成功
 15                //下面情況屬于不完全解構,但是會成功
 16                var [m,n] = [1,2,3];
 17                console.log([m,n]);
 18                
 19                //如果等号右邊不是可以周遊的結構,那麼将會報錯:
 20 //               let [foo]=1;類似這種,因為轉成對象後找不到Iterator接口。{}本身不具備Iterator接口。
 21             //對于Set結構,也可以使用數組的解構指派:
 22             let [x,y,z] = new Set(["a","b","c"]);
 23             console.log(x);
 24             
 25             //解構指派允許有預設值
 26             var [foo = true] = [];
 27             console.log(foo);
 28             //ES6内部使用嚴格相等運算符(===), 判斷一個位置是否有值。
 29             //是以如果一個數組成員不嚴格等于undefined,預設值是不會生效的。
 30 //            var [foo = 1] = [k];
 31             console.log(foo);   //預設值不生效,報錯k沒有定義
 32             var [l = 1] = [undefined];  
 33             console.log(l);     //嚴格等于undefined的時候,預設值才生效。
 34             //如果預設值是一個表達式,那麼這個表達式是惰性求值的,即隻有在生效用到的時候才會求值。
 35             //預設值也可以引用結構指派的其他變量,但該變量必須已經聲明:
 36             let [p = 1,q=p] = [2];
 37             console.log([p,q]);
 38             
 39             //數組的擴充
 40             /*
 41              * Array.from()将兩類對象轉換為真正的數組:類似數組的對象和可周遊的對象
 42              * 包括es6新增資料類型Set和Map。
 43              * 下面是一個類似數組的對象,Array.from()将它轉為真正的數組:
 44              */
 45             let arrLike = {
 46                 "0":"a",
 47                 "1":"b",
 48                 "2":"c",
 49                 length:3
 50             }
 51             //es5的寫法:
 52             var arr1 = [].slice.call(arrLike);
 53             console.log(arr1);
 54             //es6 的寫法
 55             var arr2 = Array.from(arrLike);
 56             console.log(arr2);
 57             //實際應用中,常見的類似數組的對象是DOM操作傳回的NodeList集合,以及函數内部arguments對象。
 58             //Array.from都可以将它們轉換為數組。
 59             //nodelist對象
 60             let ps = document.querySelectorAll("p");
 61             Array.from(ps).forEach(function(p){
 62                 console.log(p);
 63             })
 64             //arguments對象
 65             function test(a,...rest){
 66                 var args = Array.from(arguments);
 67                 console.log(args);
 68             }
 69             test(1,2,3,4,5,6);
 70             //隻要是部署了Iterator接口的資料,Array.from都可以将它轉換為數組。
 71             console.log(Array.from("hello"));
 72             let nameSet = new Set(["a","b"]);
 73             console.log(Array.from(nameSet));
 74             //如果參數是一個真正的數組,Array.from會傳回一個一模一樣的新數組。
 75             //值得注意的是 擴充運算符(...)也可以将某些資料結構轉為數組。
 76             //arguments對象
 77             function test2(){
 78                 var args = [...arguments];
 79                 console.log(args);
 80             }
 81             test2(2,4,5,6);
 82             //nodelist對象
 83             console.log([...document.querySelectorAll("p")]);
 84             
 85             //任何有length屬性的對象,都可以被Array.from轉成數組,但擴充運算符在這時候不能轉:
 86             console.log(Array.from({length:3}));
 87             console.log( [...{length:3}]);  //實際上也轉換成功了。 ???
 88             
 89             /*
 90              * 對于沒有部署的浏覽器可以用Array.prototype.slice方法替代。
 91              */
 92             const toArray = (() =>
 93                 Array.from ? Array.from : obj=>[].slice.call(obj)
 94             )();
 95             
 96             //Array.from還可以接受第二個參數,作用類似于數組的map方法,用來對每個元素進行處理,
 97             //将處理後的值放入傳回的數組。
 98             Array.from(arrLike,x=>x*x);
 99             //等同于
100              Array.from(arrLike).map(x=>x*x);
101              
102              console.log(Array.from([1,2,3],x=>x*x));
103              
104              //用途比較廣,dom操作,到數組值得轉換,到傳回一組資料的資料類型。
105              function typesOf(){
106                  return Array.from(arguments,value=>typeof value)
107              }
108              console.log(typesOf("s",1,Number,[]))
109              
110              //如果map函數裡用到了this關鍵字,還可以傳入Array.from的第三個參數,用來綁定this。
111              
112              //隻要有一個原始的資料結構,就可以對它的值進行處理,然後轉成規範的數組,進而使用數組的方法。
113              console.log(Array.from({length:2},()=>"jack"));
114              //上面代碼中,第一個參數,指定了第二個參數的運作次數,這種特性可以讓該方法的方法變得非常靈活。
115              
116              //另一個應用是将字元串轉為數組,然後傳回字元串的長度,這樣可以正确處理各種Unicode字元,可以
117              //避免将大于uFFFF的Unicode字元,算作兩個字元的bug。
118              
119              function countSymbols(string){
120                  return Array.from(string).length;
121              }
122              
123              
124              //Array.of()将一組值,轉換為數組。
125              console.log(Array.of(3,11,8));
126              console.log(Array.of(3));
127              console.log(Array.of(3,11,8).length);
128              //這個方法的主要目标是彌補數組構造函數的不足。因為參數個數不同,會導緻Array()的行為有差異。
129              console.log(Array());  //[]
130              console.log(Array(3));  //[,,]
131              console.log(Array(3,8,4)); //[3,8,4]
132              // 上面代碼中,Array方法參數為0,1,3時候,傳回結果都不一樣,隻有當參數個數不少于2個時,Array才會傳回 
133              //由參數組成的額數組,一個參數時,實際上是在指定數組長度。
134              
135              //Array.of() 基本上可以用來替代Array或new Array(), 并且不存在由于參數不同而導緻的重載。行為非常統一。
136              //Array.of()總是傳回由參數值組成的數組。如果參數沒有值,就傳回一個空數組。
137              //Array.of()可以用下面的代碼模拟實作:
138              function Arrayof(){
139                  return [].slice.call(arguments);
140              }
141             
142             
143             /*
144              * 數組執行個體的copyWithin
145              * 在目前的數組内部,将指定位置的成員複制到其他位置(會覆寫原有成員),然後返目前數組,也就是說,使用這個方法,會修改目前數組。
146              * Array.prototype.copyWithin(target,start=0,end=this.length);
147              * 接收三個參數:
148              *    target:從該位置開始替換資料;
149              *    start:從該位置開始讀取資料,預設為0,如果為負值,表示倒數。
150              *    end:到該位置停止讀取資料,預設等于數組長度。如果是負值,表示倒數。
151              * 這三個都應該是數值,如果不是,自動轉換。
152              */
153             console.log([1,2,3,4,5].copyWithin(0,3));
154             //将3号位複制到0号位
155             console.log([].copyWithin.call({length:5,3:1},0,3));
156             
157             //不再舉例
158             
159             /*
160              * 數組執行個體的find()和findIndex()
161              * find()方法用于找出第一個符合條件的數組成員。它的參數是一個回調函數,
162              * 所有數組成員依次執行該回調函數,直到找出第一個傳回值為true的成員,然後傳回該成員。
163              * 如果沒有符合條件的成員,傳回undefined。
164              */
165             console.log([1,2,-5,7].find(x=>x<0));  //-5
166             console.log([1,5,10,15].find(function(value,index,arr){
167                 return value > 9;
168             }))  //10
169             //上面代碼中,find的回調函數有三個參數,值,索引,原數組。
170             
171             //findIndex方法的用法與find方法非常類似,傳回一個符合條件的數組成員的索引,都不符合就傳回-1。
172              console.log([1,5,10,15].findIndex(function(value,index,arr){
173                 return value > 9;
174             }))  //2 索引
175             //這兩個方法都可以接受第二個參數,用來綁定回調函數的this對象。
176              //另外這兩個方法都可以發現NaN,彌補了數組IndexOf方法的不足。
177              console.log([NaN].indexOf(NaN))  //-1
178              console.log([NaN].findIndex(y=>Object.is(NaN,y)));  //0
179              /*
180               * 關于Object.is()  多數時候與"===" 等價,
181               * 但對于NaN、0、+0、 -0,則和 “===” 不同。
182               * 也就是用Object.is(NaN,NaN) //true
183               * Object.is(0,-0) //false 
184               * Object.is(+0,-0) //false
185               */
186              
187              
188              /*
189               * 數組執行個體的fill()
190               * 使用給定值,填充一個數組。相當于重寫。
191               * 接受第二和第三個參數,用于指定填充的起始位置和結束位置(不包括結束的位置)。
192               */
193              console.log([1,2,3].fill("a"));  //[a,a,a]
194              console.log(new Array(3).fill(4));  //[4,4,4]
195              console.log([1,2,3,4,5,6].fill("a",2,4))  //[1,2,a,a,5,6]
196              
197              
198              /*
199               * 數組執行個體的entries(),keys(),values()用于周遊數組。
200               * 都傳回一個Iterator對象,用for of循環,差別是
201               * keys()是對鍵名的周遊,values()是對鍵值的周遊,entries是對鍵值對的周遊。
202               */
203              for(let index of ["a","b"].keys()){
204                  console.log("index:",index);
205              }
206              for(let ele of [1,2,3]){
207                 //values這個方法好像找不到了。應該換成了這樣的寫法
208                  console.log("value:",ele);
209              }
210              for(let [index,ele] of ["a","b"].entries()){
211                  console.log("key-val:",index,ele);
212              }
213              //下面這個倒是可以用的,但是是綁定在Object上的。
214             var obj = {"a":"html","b":"javascript"};
215             console.log(Object.values(obj));
216         //如果不使用for of循環,可以用手動的next進行周遊:
217         let letter = ["a","b","v"];
218         let entries = letter.entries();
219         console.log(entries.next().value);
220         console.log(entries.next().value);
221         console.log(entries.next().value);
222         console.log(entries.next().value); //超過了長度就是undefined
223         
224         /*
225          * 數組執行個體的includes(),傳回一個布爾值,表示某個數組是否包含給定的值,與字元串的
226          * includes類似,屬于es7,但babel已經支援。
227         */
228         console.log([1,2,3].includes(2));  //true
229         console.log([1,2,3].includes(4));  //false
230         console.log([1,2,NaN].includes(NaN)); //true
231         //該方法的第二個參數表示搜尋的起始位置,預設為0,如果第二個參數為負數,
232         //表示倒數,如果這是它大于數組的長度,則會重置為從0開始。
233         //沒有這個方法之前,都是用數組的indexOf方法,檢查是否包含某個值。
234         //indexOf的缺點:不夠語義化,他要找到參數出現的第一個位置,是以要和-1比較,
235         //            内部使用===判斷,對NaN誤判。
236         console.log([NaN].includes(NaN));  //true
237         //下面的代碼檢查目前環境是否支援該方法,如果不支援,部署一個簡易版本:
238         const contains = (()=>
239             Array.prototype.includes?(arr,value)=>arr.includes(value)
240             :(arr,value)=>arr.some(el=>el===value)
241         )();
242         console.log(contains(["foo","baz"],"baz"));
243         /*
244          *另外,Map和Set資料結構有一個has方法,需要注意與includes區分。
245          * Map的has方法,用來查找鍵名的。
246          * Set的has方法,用來查找值的。
247          */
248         
249         
250         /*
251          * 數組的空位:
252          * 空位不是undefined,一個位置的值等于undefined,依然是有值的。
253          * 空位是米有任何值的。
254          */
255         console.log( 0 in [undefined]);  //true
256         console.log( 0 in [,]);    //false
257         /*
258          * 上面代碼說明,第一個數組的0号位置是有值的,第二個數組的0号位是沒有值的。
259          * es5對空位的處理很不一緻,大多數情況,跳過空位。
260          * forEach(),filter(),every(),some()都會跳過空位。
261          * map()會跳過空位,但會保留這個值
262          * join()和toString()會将空位視為undefined,而undefined和null會被
263          * 處理成空字元串。
264          * 
265          * es6明确将空位轉為undefined。
266          * Array.from會将數組的空位轉為undefined,也就是不會忽略空位。
267          */
268         console.log(Array.from(["a",,"b"])); //[a,undefined,b]
269         //擴充運算符也将空位轉為undefined
270         console.log([...["a",,"b"]]);  //[1,undefined,2]
271         //上面代碼實測的時候,結果是[a,2:b]; 并沒有undefined。      

  依賴檔案位址:https://github.com/chanceLe/ES6-Basic-Syntax/tree/master/js