for迴圈替代解決方案

2022-10-08 23:48:21 字數 4816 閱讀 3489

**:

幾種遍歷方法中for執行最快,它沒有任何額外的函式呼叫棧和上下文。但在實際開發中我們要結合語義話、可讀性和程式效能,去選擇究竟使用哪種方案。下面來看for , foreach , map ,for...in , for...of五種方法現場battle。

for我是最早出現的一方遍歷語句,在座的各位需稱我一聲爺爺。我能滿足開發人員的絕大多數的需求。

let arr = [1,2,3];

for(let i = 0;i < arr.length;i++)

// 遍歷物件

let profile = ;

for(let i = 0, keys=object.keys(profile); i < keys.length;i++)

// 遍歷字串

let str = "abcdef";

for(let i = 0;i < str.length ;i++)

// 遍歷dom 節點

let articleparagraphs = document.queryselectorall('.article > p');

for(let i = 0;iforeach

我是es5版本發布的。按公升序為陣列中含有效值的每一項執行一次 callback 函式,那些已刪除或者未初始化的項將被跳過(例如在稀疏陣列上)。我是 for 迴圈的加強版。

// 遍歷陣列

let arr = [1,2,3];

arr.foreach(i => console.log(i))

// logs 1

// logs 2

// logs 3

// 直接輸出了陣列的元素

//遍歷物件

let profile = ;

let keys = object.keys(profile);

keys.foreach(i => )

map

我也是es5版本發布的,我可以建立乙個新陣列,新陣列的結果是原陣列中的每個元素都呼叫一次提供的函式後的返回值。

let arr = [1,2,3,4,5];

let res = arr.map(i => i * i);

console.log(res) // logs [1, 4, 9, 16, 25]

for...in列舉

我是es5版本發布的。以任意順序遍歷乙個物件的除symbol以外的可列舉屬性。

// 遍歷物件

let profile = ;

for(let i in profile)

for...of迭代

我是es6版本發布的。在可迭代物件(包括 array,map,set,string,typedarray,arguments 物件等等)上建立乙個迭代迴圈,呼叫自定義迭代鉤子,並為每個不同屬性的值執行語句。

// 迭代陣列陣列

let arr = ['a','b','c'];

for(let item of arr)

// logs 'a'

// logs 'b'

// logs 'c'

// 迭代字串

let str = "abc";

for (let value of str)

// logs 'a'

// logs 'b'

// logs 'c'

// 迭代map

let iterable = new map([["a", 1], ["b", 2], ["c", 3]]

for (let entry of iterable)

// logs ["a", 1]

// logs ["b", 2]

// logs ["c", 3]

// 迭代map獲取鍵值

for (let [key, value] of iterable)

// 迭代set

let iterable = new set([1, 1, 2, 2, 3, 3,4]);

for (let value of iterable)

// logs 1

// logs 2

// logs 3

// logs 4

// 迭代 dom 節點

let articleparagraphs = document.queryselectorall('.article > p');

for (let paragraph of articleparagraphs)

// 迭代arguments類陣列物件

(function()

})(1, 2, 3);

// logs:

// 1

// 2

// 3

// 迭代型別陣列

let typearr = new uint8array([0x00, 0xff]);

for (let value of typearr)

// logs:

// 0

// 255

經過第一輪的自我介紹和技能展示後,我們了解到:

作為乙個程式設計師,僅僅認識他們是遠遠不夠的,在實際開發中鑑別他們各自的優缺點。因地制宜的使用他們,揚長避短。從而提高程式的整體效能才是能力之所在。

關於跳出迴圈體

在迴圈中滿足一定條件就跳出迴圈體,或者跳過不符合條件的資料繼續迴圈其它資料。是經常會遇到的需求。常用的語句是break 與 continue。

簡單的說一下二者的區別,就當複習好了。

break語句是跳出當前迴圈,並執行當前迴圈之後的語句;

continue語句是終止當前迴圈,並繼續執行下一次迴圈;

注意:foreach 與map 是不支援跳出迴圈體的,其它三種方法均支援。

原理 :檢視foreach實現原理,就會理解這個問題。

array.prototype.foreach(callbackfn [,thisarg]
傳入的function是這裡的**函式。在**函式裡面使用break肯定是非法的,因為break只能用於跳出迴圈,**函式不是迴圈體。

在**函式中使用return,只是將結果返回到上級函式,也就是這個for迴圈中,並沒有結束for迴圈,所以return也是無效的。

map() 同理。

map()鏈式呼叫

map() 方法是可以鏈式呼叫的,這意味著它可以方便的結合其它方法一起使用。例如:reduce(), sort(), filter() 等。但是其它方法並不能做到這一點。foreach()的返回值是undefined,所以無法鏈式呼叫。

// 將元素乘以本身,再進行求和。

let arr = [1, 2, 3, 4, 5];

let res1 = arr.map(item => item * item).reduce((total, value) => total + value);

console.log(res1) // logs 55 undefined"

for...in會遍歷出原型物件上的屬性

object.prototype.objcustom = function() {};

array.prototype.arrcustom = function() {};

var arr = ['a', 'b', 'c'];

arr.foo = 'hello

for (var i in arr)

// logs

// 0

// 1

// 2

// foo

// arrcustom

// objcustom

然而在實際的開發中,我們並不需要原型物件上的屬性。這種情況下我們可以使用hasownproperty() 方法,它會返回乙個布林值,指示物件自身屬性中是否具有指定的屬性(也就是,是否有指定的鍵)。如下:

object.prototype.objcustom = function() {};

array.prototype.arrcustom = function() {};

var arr = ['a', 'b', 'c'];

arr.foo = 'hello

for (var i in arr)

}// logs

// 0

// 1

// 2

// foo

// 可見陣列本身的屬性還是無法擺脫。此時建議使用 foreach

對於純物件的遍歷,選擇for..in列舉更方便;對於陣列遍歷,如果不需要知道索引for..of迭代更合適,因為還可以中斷;如果需要知道索引,則foreach()更合適;對於其他字串,類陣列,型別陣列的迭代,for..of更占上風更勝一籌。但是注意低版本瀏覽器的是配性。

有興趣的讀者可以找一組資料自行測試,文章就直接給出結果了,並做相應的解釋。

for > for-of > foreach > map > for-in

在實際開發中我們要結合語義話、可讀性和程式效能,去選擇究竟使用哪種方案。

如果你需要將陣列按照某種規則對映為另乙個陣列,就應該用 map。

如果你需要進行簡單的遍歷,用 foreach 或者 for of。

如果你需要對迭代器進行遍歷,用 for of。

如果你需要過濾出符合條件的項,用 filterr。

如果你需要先按照規則對映為新陣列,再根據條件過濾,那就用乙個 map 加乙個 filter。

總之,因地制宜,因時而變。千萬不要因為過分追求效能,而忽略了語義和可讀性。在您的統治之下,他們5個只能是各自發揮長處,誰都別想稱霸。

Spring Bean 迴圈依賴解決方案

由於service層互相呼叫,一下子沒有什麼好的拆分方案,所以先解決迴圈依賴問題。現有aservice 和bservice,都在對方bean中注入,導致初始化時迴圈初始報錯,解決方案就是選擇其一使其延遲載入。用配置方式只要將其一設定lazy init,具體沒嘗試過因為不適用配置申明的方式。然後從上下...

巨集在C 中的替代解決方案

1.常量定義 例如 define num 100替換為 const int num 100 const常量放在標頭檔案中,也不必擔心存在多個例項的問題,對於const修飾的變數,編譯器一般也會對其進行優化,不會出現多重定義的問題。c語言中還有乙個特殊的常量定義 null。其一般的定義為 define...

Spring迴圈依賴的解決方案

什麼是迴圈依賴?迴圈 倆字就足以表明含義了,舉個例子 在例項化a類時需要依賴到b類的例項,而恰好b類例項也依賴到a類。如圖所示 spring在例項化類a時發現需要類b的例項,所以會先去例項化b類,但是又發現b類需要a類的例項 wtf?這樣迴圈下去肯定會出問題的,所以乾脆丟擲beancurrently...