簡體   English   中英

像 .map() 這樣的高階函數如何在 JavaScript 內部工作?

[英]How do higher-order functions, like .map(), work internally in JavaScript?

現在每個人都試圖使用這些高階函數來通過編寫更少的代碼來獲得有希望的結果。 但我想知道這些功能在內部是如何工作的。

假設我寫了類似的東西

 var numbers = [16, 25, 36]; var results = numbers.map(Math.sqrt); console.log(results); // [4, 5, 6]

我知道 'number' 數組的每個元素都在一個一個地迭代,但是如何

我試圖搜索它,但我還沒有得到任何滿意的答案。

.map只是一個方法,它接受一個回調,為數組的每一項調用回調,並將值分配給一個新數組。 沒有什么特別之處。 你甚至可以很容易地自己實現它:

 Array.prototype.myMap = function(callback) { const newArr = []; for (let i = 0; i < this.length; i++) { newArr.push(callback(this[i], i, this)); } return newArr; } var numbers = [16, 25, 36]; var results = numbers.myMap(Math.sqrt); console.log(results); // [4, 5, 6]

為了完全規范兼容的,你還需要檢查,除其他事項外, this是一個對象,該callback是可調用,並.call與傳遞給第二個參數回調myMap如果有,但這些細節對於開始理解高階函數並不重要。

我想每個供應商都應該按照規范來實現它

實際實現,例如 V8 可能有點復雜,請參考這個答案開始。 也可以參考github中的v8源碼,但是單獨看一部分可能不太好理解。

引自上面的回答:

V8 開發人員在這里。 我們有幾種不同的“內置”實現技術:有些是用 C++ 編寫的,有些是用 Torque 編寫的,有些是我們稱之為 CodeStubAssembler 的,還有一些是直接用匯編編寫的。 在 V8 的早期版本中,有些是用 JavaScript 實現的。 這些策略中的每一個都有自己的優勢(權衡代碼復雜性、可調試性、各種情況下的性能、二進制大小和內存消耗); 此外,代碼隨着時間的推移而發展總是有歷史原因的。

ES2015 規范:

  1. O成為 ToObject(這個值)。
  2. ReturnIfAbrupt( O )。
  3. len為 ToLength(Get( O , "length" ))。
  4. ReturnIfAbrupt( len )。
  5. 如果 IsCallable( callbackfn ) 為false ,則拋出TypeError異常。
  6. 如果提供了thisArg ,則設TthisArg 否則讓Tundefined
  7. A為 ArraySpeciesCreate( O , len )。
  8. ReturnIfAbrupt( A )。
  9. k為 0。
  10. 重復,而k < len
    1. Pk為 ToString( k )。
    2. kPresentHasProperty ( O , Pk )。
    3. ReturnIfAbrupt( kPresent )。
    4. 如果kPresenttrue ,則
      1. kValue為 Get( O , Pk )。
      2. ReturnIfAbrupt( kValue )。
      3. 映射值是調用(回調函數T ,« kValue , k , O »)。
      4. ReturnIfAbrupt( mappedValue )。
      5. status為 CreateDataPropertyOrThrow ( A , Pk , mapsValue )。
      6. ReturnIfAbrupt(狀態)。
    5. k增加 1。
  11. 返回A

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM