1. 程式人生 > >for,(for...in...),forEach(...),(for...of..)差異與原理淺析

for,(for...in...),forEach(...),(for...of..)差異與原理淺析

for

    下面是for迴圈的語法:

for(語句1;語句2;語句3){
    被執行的程式碼塊
}
  • 語句1:在迴圈(程式碼塊)開始前執行,通常用來初始化迴圈中的變數(任意個)。
  • 語句2:定義執行迴圈(程式碼塊)的條件,用來評估初始變數的條件,如果語句 2 返回 true,則迴圈再次開始,如果返回 false,則迴圈將結束。
  • 語句3:在迴圈(程式碼塊)已被執行之後執行,用來增加初始變數的值。

    這三個語句都是可選的。
    以 jquery中.unwrap()的原始碼分析作為案例(非官方分析,編寫的小demo罷了)

 function unwrap(element)
{
var parentElement = element.parentNode; var children = parentElement.children; for (; children.length; ) { parentElement.parentNode.insertBefore(children[0], parentElement); } parentElement.parentNode.removeChild(parentElement); }

    在上述程式碼中,需要將要去除元素的父元素。做法是將element的子元素用for迴圈挨個插入到element的父級元素之前,迴圈完成後就將element的父元素刪除。在迴圈中,不需要初始化迴圈中的變數和改變迴圈變數的值,因為在不斷的insertBefore操作中,迴圈條件在不斷改變。

    檢視程式碼的執行,可以清楚地知道for迴圈實際上是遍歷下標來指向值。因此它更適用於操作迴圈次數已知且具有數字下標的資料。

(for…in…)

   for(var s in obj){//obj為物件
     console.log(s,obj[s]);//打印出obj內的屬性名和屬性值  
   }

    (for…in…)的特徵總結如下:
- (for…in…)用來迴圈物件的所有屬性,其實準確的來說,是迴圈物件的可列舉屬性;
- 如果想要獲取到迴圈物件的屬性值,則需要手動再獲取(如obj[s]),而且物件的屬性不一定包含值,它們可能是具備getter/setter的訪問描述符;
- (for…in…)可以訪問到物件原型鏈上的資料;
- (for…in…)是為普通物件設計的,你可以遍歷得到字串型別的鍵

    所以為什麼不推薦使用(for…in)來遍歷陣列呢?原因就在於這種列舉不僅會包含所有數值索引還會包含所有可列舉屬性,在某些情況下,可能按照隨機順序遍歷陣列元素。

Array.forEach( )

array.forEach(function(currentValue,index,arr){},thisValue);
  • forEach為es6新增的輔助迭代器,作用是對呼叫者的元素進行遍歷並進行相關操作;
  • 僅能被陣列或者使用document.querySelectorAll獲取到的類陣列進行呼叫;
  • 第一個引數為回撥函式,其接收的引數依次為當前元素(必填),當前元素的索引值(可選),當前物件所屬的陣列物件;第二個引數可以限定回撥函式內this的指向;
  • 在回撥函式內部無法使用break來跳出迴圈,也不能使用return來返回外層函式

    由它的特性可以推斷出forEach的實現程式碼如下:

 Array.prototype.forEach = function(callback, context) {
            for (var i=0; i<this.length; i++) {
                callback.call(context, this[i], i);
            }
        };

(for … of …)

    先說下(for…of…)的作用,它與(for…in…)不同,它是用來遍歷資料,如物件裡的屬性值。

    而說到(for…of…)就必須提到迭代協議和迭代器。因為不是所有的物件都可以被for…of的,只有實現了迭代器(迭代協議)的物件才可以for…of 。
for..of會尋找內建的或者自定義的@@iterator物件並呼叫它的next()。具體流程如下:
1. 首先呼叫(for…of…)的物件的屬性裡必須有一個函式,它的函式名必須為Symbol.iterator;
2. 該函式的返回值必須為一個物件,且物件內包含一個next()函式;
3. next()函式也必須有一個返回值,返回值型別也為一個物件。其包含兩個屬性:done和value。
4. 程式會根據該物件的done來處理後續行為,如果done為false,則把該物件的value賦值給of前面的變數。否則就會繼續呼叫next,直至done為true再終止。

    由它的特性可以推斷出(for…of…)的實現程式碼如下:

 obj[Symbol.iterator] = function() {
        let keys = Object.keys(obj);
        var n = keys.length;
        var i = 0;
        return {
            next() {
                if (i < n) {
                    let key = keys[i];
                    i++;
                    return {done: false, value: { obj[key]}
                } else {
                    return {done: true}
                }
            }
        }
    };

    我們可以來分析下它與其他迴圈的不同:
1. 與forEach()不同的是,(for…of…)可以正確響應break、continue和return語句;
2. 與(for..in…)相比,除了能夠快速的得到屬性值外,它還避開了(for…in…)所有的缺陷;
3. (for..of…)迴圈不僅支援陣列,還支援大多數類陣列物件,例如DOM NodeList物件;
4. (for..of…)迴圈也支援字串遍歷,它將字串視為一系列的Unicode字元來進行遍歷;

相關推薦

for,(for...in...),forEach(...),(for...of..)差異原理淺析

for     下面是for迴圈的語法: for(語句1;語句2;語句3){ 被執行的程式碼塊 } 語句1:在迴圈(程式碼塊)開始前執行,通常用來初始化迴圈中的變數(任意個)。 語句2:定義執行迴圈(程式碼塊)的條件,用來評估初始變數的條件,

for系迴圈(for,for in,forEach,for of)一較高下~

想先說幾句,我編輯即將完成的文章,因為不小心按錯了滑鼠鍵,就一切完犢子了。 都2018年了,網際網路世界依然會發生這種痛心疾首的小事情,我不知道該和CSDN說點什麼……。 ----------------------------------回到正文------------

for each...infor...infor...of

一、for  each ...in  complain:   該語句在物件屬性的所有值上迭代指定的變數。對於每個不同的屬性,執行指定的語句。 句法: for each (variable in object) {statement}   &

for …each…infor infor of

logs tro 屬性。 htm ring () docs main 接口 一、一般的遍歷數組的方法: var array = [1,2,3,4,5,6,7]; for (var i = 0; i < array.length; i) {

The case for humanities in the era of AI, automation, and technology

Whether we're working side-by-side with autonomous robots on the factory floor, spreading the happy news about a new addition to the family on Facebook, or

for each....infor infor of

一、一般的遍歷陣列的方法: var array = [1,2,3,4,5,6,7]; for (var i = 0; i < array.length; i) { console.log(i,array[i]); } 二

for each...infor...in

for...in 官方解釋:for...in語句以任意順序遍歷一個物件的可列舉屬性。對於每個不同的屬性,語句都會被執行。 語法:for (變數 in 物件) { 在此執行程式碼(每次迴圈一次,就會把這個物件的屬性賦值給這個變數,然後就可以來檢視有哪些屬性,或者更改屬性等) }1.迭代中增加屬性

java.util.concurrent.Exchanger應用範例原理淺析

java.util.concurrent.Exchanger應用範例與原理淺析--轉載 一、簡介    Exchanger是自jdk1.5起開始提供的工具套件,一般用於兩個工作執行緒之間交換資料。在本文中我將採取由淺入深的方式來介紹分析這個工具類。首先我

SpringBoot魔法堂:應用熱部署實踐原理淺析

# 前言 後端開發的同學想必每天都在重複經歷著修改程式碼、執行程式碼編譯,等待……重啟Tomcat服務,等待……最後測試發現還是有bug,然後上述流程再來一遍(我聽不見):( 能不能像前端開發的同學那樣,修改程式碼儲存檔案後自動編譯、重新載入應用呢?Spring Boot給了我們一個大大的Yes! 本文

for-infor-offorEach和Map

循環對象 共同點 school 遍歷 fine 不能 name pre 包括 for-in和for-of   1.  for-in循環實際是為循環”enumerable“對象而設計的,是用來循環帶有字符串key的對象的。    使用for in會遍歷數組所有的可枚舉屬性,包

for,forEach,for in ,for of,$.each和$().each應用

In 我們 應用 你我 幫助 感覺 別人 收益 必須 今天嚴重的意識到,只看不總結,就如同走馬觀花,得到的也必是浮光掠影,看完以後感覺自己學富五車,才高八鬥,實則不辨菽麥,前輩們說的一點也不錯,寫博客這件事必須的堅持,因為誰也不想讓自己的博客變成自己都不願意進的垃圾站,所以

forEachfor infor of循環的用法

for iterator 對象 復制 efi type 統一 undefined 數組 一、一般的遍歷數組的方法: var array = [1,2,3,4,5,6,7]; for (var i = 0; i < array.length; i)

for each in for in for of

for each in   for each in是作為E4X標準的一部分在javascript 1.6中釋出的,而它不是ECMAScript標準的一部分。  這將意味著存在各種瀏覽器的相容性問題。for each in,對很多瀏覽器都不支援的。例如是不支援IE6,IE7

For each...in / For...in / For...of 的解釋例子

1、For each...in   for each...in 語句在物件屬性的所有值上迭代指定的變數。對於每個不同的屬性,執行一個指定的語句。 語法: for each (variable in object) { statement } variable: 變數,以迭代

for each in for infor of

搜索 scrip cti nta iterator for 找到 可選 value 1.for each in 語法: for each (variable in object) { statement }參數: variable用來遍歷屬性值的變量,前面的var關鍵字

js 中forEach for in for of

ForEach和map的區別 相同點: 都是迴圈遍歷陣列中的每一項 forEach和map方法裡每次執行匿名函式都支援3個引數,引數分別是item(當前每一項)、index(索引值)、arr(原陣列) 匿名函式中的this都是指向window 只能遍歷陣列不同點

for...infor...offorEach、map的區別

for…in for…in以原始插入順序訪問物件的可列舉屬性,包括從原型繼承而來的可列舉屬性。 let obj = { a:123, b:"abc" } for(let pro in obj){ console.log(pro+':' + obj[pro]

forEachfor...infor..of比較

forEach是遍歷陣列中的值: var arr=['one','two','three']; arr.forEach(function(value){ console.log(value); }) //one //two //three 這種寫法的問題在於,無法中途跳出forE

js遍歷for,forEach,for-in,for-of之間的區別

在js中經常要是用for迴圈遍歷陣列,物件;那for, forEach, for in, for of,之間有什麼區別呢? let arr = [1,2,3,4,5] a.a = 'a' for 原始的遍歷方法 程式設計式 for(var i =

js中forEachfor infor of迴圈的用法

一、一般的遍歷陣列的方法: var array = [1,2,3,4,5,6,7]; for (var i = 0; i < array.length; i) { console.log(i,array[i]); } 二、用for i