【JavaScript學習筆記】8:for-in遍曆,ES6的for-of遍曆,可迭代對象的forEach()方法__Java

來源:互聯網
上載者:User
回顧for-in遍曆

在js裡,for-in遍曆的是可迭代對象的key,這點需要特別注意:

"use strcit";var x=['lz','h','is','a sb']; //Array對象是可迭代的for(let i in x){    console.log(i); //用for-in遍曆輸出看一下}

輸出

0123
不方便之處

如果要擷取它的值,就需要再去查詢一次這個key所對應的值:

"use strcit";var x=['lz','h','is','a sb']; //Array對象是可迭代的for(let i in x){    console.log(x[i]); //i是key,而x[i]就是i在x中對應的value}

輸出

lzhisa sb

這種方法顯然有些低效,而且語義上不是那麼直觀,我想要遍曆的只是數組裡的各個元素,為什麼要使用key呢。 嘗試遍曆Set時存在的問題

如果嘗試用這種方式去遍曆Set,前面學了Set可以看成只儲存key的索引值對系,但是卻擷取不到東西:

"use strcit";var x=new Set(['lz','h','is','a sb']); //Set對象是可迭代的for(let i in x){    console.log(i); //如果i視為object的key,嘗試訪問key去遍曆Set}

輸出(沒東西)

 

我認為這可能體現了Set的無序性,總之沒能遍曆它。 嘗試遍曆Map時存在的問題

Map底層基於樹來實現,它的key大抵也是無序的,沒法遍曆:

"use strcit";var x=new Map([[6,'lz'],[7,'h'],[7.5,'is'],[9.2,'a sb']]); //Map對象是可迭代的for(let i in x){    console.log(i); //如果i視為object的key,嘗試訪問key去遍曆Map的每個鍵}

輸出(沒東西)

 
for-of遍曆 
用於Set 

for-of遍曆對於Set遍曆的是集合中的值:

"use strcit";var x=new Set(['lz','h','is','a sb']);for(let i of x){    console.log(i);}

輸出

lzhisa sb
用於Map

for-of遍曆對於Map遍曆的是索引值對的Array形式:

"use strcit";var x=new Map([[6,'lz'],[7,'h'],[7.5,'is'],[9.2,'a sb']]);for(let i of x){    console.log(i);}

輸出

Array [ 6, "lz" ]Array [ 7, "h" ]Array [ 7.5, "is" ]Array [ 9.2, "a sb" ]
用於Array

for-of遍曆對於Arrayt遍曆的是其每個元素的值:

"use strcit";var x=new Array('lz','h','is','a sb');for(let i of x){    console.log(i);}

輸出

lzhisa sb
還有一些差異 在處理Object對象時的差異

for-of是ES6標準下的,在這之前就存在的for-in將Object也視為可迭代對象,遍曆出的是對象的各個屬性和方法的名稱:

"use strcit";//為這個Object對象添加了4個屬性2個方法var ok={    sb1:'lz',    sb2:'h',    sb3:'is',    sb4:'a sb',    myfun1:function(x,y){        return x+y;    },    myfun2:function(x,y){        return x-y;    }   };for(let i in ok){    console.log(i);}

輸出

sb1sb2sb3sb4myfun1myfun2

ES6標準不認為Object對象是可迭代的,只認Map,Set,Array,所以不能用for-of遍曆之:

"use strcit";//Object對象var ok={    sb1:'lz',    sb2:'h',    sb3:'is',    sb4:'a sb',    myfun1:function(x,y){        return x+y;    },    myfun2:function(x,y){        return x-y;    }   };for(let i of ok){    console.log(i); //嘗試用for-of遍曆之}

輸出(報錯)

TypeError: ok is not iterable
為可迭代對象新增成員時的差異

從for-in的角度來看,Map和Set遍曆不了,Object本來就是由各個成員變數和成員方法組成的,而for-in又認為Object可迭代,新增成員能遍曆是理所當然的。

所以新增成員時的差異只要去看Array對象。

為Array對象新增成員時,for-in會把這個成員和其它下標同一地視為key去遍曆到:

"use strcit";var ok=["lzh","is","rubbish","sb","big sb dog"];ok.name="SBLZH"; //為這個Array對象添加一個成員變數//為這個Array對象添加一個成員方法ok.myfun=function(x,y){    return x+y;};//嘗試用for-in遍曆之for(let i in ok){    console.log(ok[i]);}

輸出

lzhisrubbishsbbig sb dogSBLZHfunction ok.myfun()

現在,如果只有for-in,被添加了成員的Array對象變得很難用了。

而for-of會正確的區分成員和其內容:

"use strcit";var ok=["lzh","is","rubbish","sb","big sb dog"];ok.name="SBLZH"; //為這個Array對象添加一個成員變數//為這個Array對象添加一個成員方法ok.myfun=function(x,y){    return x+y;};//嘗試用for-of遍曆之for(let i of ok){    console.log(i); //注意這裡不需要ok[i]了,只要用一個i}

輸出

lzhisrubbishsbbig sb dog
可迭代對象的forEach()方法

forEach方法接收一個函數為參數,這樣傳進來的函數稱為callback回呼函數

在每次迭代的過程中都會為這個函數傳入一些參數來調用它一次,當然形參的名字是任意合法的都一樣。用這個forEach()方法就可以把遍曆+做事情寫的非常簡潔了。

對於Object對象,ES6已經明確指出它不是可迭代對象,Object對象自然沒有forEach()方法。 屬於Array對象的forEach()方法

"use strcit";var ok=["lzh","is","rubbish","sb","big sb dog"];var control=false; //用於控制只在第一次輸出對象自己ok.forEach(    //傳進來三個參數依次是(目前的元素值,目前的下標,本數組)    function(now_element,now_index,thisArray){        //第三個參數每次迭代都一樣的,只輸出一次看一下就好        if(control===false){            control=true;            console.log("這個Array是"+thisArray);            console.log("第3個參數的類型是"+typeof thisArray);        }        console.log("ok["+now_index+"]="+now_element);    });

輸出

這個Array是lzh,is,rubbish,sb,big sb dog第3個參數的類型是objectok[0]=lzhok[1]=isok[2]=rubbishok[3]=sbok[4]=big sb dog
屬於Set對象的forEach()方法

注意在Set對象上使用時傳進來的前兩個參數是完全一樣的。

"use strcit";var ok=new Set(["lzh","is","rubbish","sb","big sb dog"]);var control=false; //用於控制只在第一次輸出對象自己ok.forEach(    //傳進來三個參數依次是(目前的元素值,目前的元素值,本集合)    //畢竟Set作為集合不涉及下標(無序),傳進來的前兩個參數都是元素值    function(now_element,now_elem,thisSet){        //第三個參數每次迭代都一樣的,只輸出一次看一下就好        if(control===false){            control=true;            console.log("這個Set是"+thisSet);            console.log("第3個參數的類型是"+typeof thisSet);        }        console.log("第1個參數="+now_element);        console.log("第2個參數="+now_elem);    });

輸出

這個Set是[object Set]第3個參數的類型是object第1個參數=lzh第2個參數=lzh第1個參數=is第2個參數=is第1個參數=rubbish第2個參數=rubbish第1個參數=sb第2個參數=sb第1個參數=big sb dog第2個參數=big sb dog
屬於Map對象的forEach()方法
"use strcit";var ok=new Map([[7,"lzh"],[8.5,"is"],['666阿',"rubbish"],[-30,"sb"],[250,"big sb dog"]]);var control=false; //用於控制只在第一次輸出對象自己ok.forEach(    //傳進來三個參數依次是(目前的value,目前的key,本Map)    function(now_value,now_key,thisMap){        //第三個參數每次迭代都一樣的,只輸出一次看一下就好        if(control===false){            control=true;            console.log("這個Set是"+thisMap);            console.log("第3個參數的類型是"+typeof thisMap);        }        console.log("ok["+now_key+"]="+now_value);    });

輸出

這個Set是[object Map]第3個參數的類型是objectok[7]=lzhok[8.5]=isok[666阿]=rubbishok[-30]=sbok[250]=big sb dog

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.