2017-11-25 178 views
0

我寫了一個函數:關於JavaScript函數的valueOf 的toString和 '咖喱' 功能在Chrome,Firefox的不同表現和節點環境

function add(){ 
    let arr = []; 
    arr = arr.concat(Array.prototype.slice.apply(arguments)) 
    let fun = function(){ 
     arr = arr.concat(Array.prototype.slice.apply(arguments)) 
     return fun 
    } 
    fun.toString = function(){ 
     console.log(222) 
     return arr.reduce(function(total, num){ 
      return total+num 
     }, 0) 
    } 
    return fun 
} 
console.log(add(1,2)(2,3)(3)) 

這是在Chrome: enter image description here

兩個問題:

  1. 在第一行,爲什麼是'f 11'而不是'11'

  2. 爲什麼首先輸出'f 11',而不是'222',我認爲應該先執行類型轉換,然後在控制檯上輸出計算結果。

另一種奇怪的東西,它是與相同的代碼,結果在Firefox: enter image description here

而導致節點環境: enter image description here

我不明白爲什麼,似乎在FF和節點,還沒有執行計算的操作。

請幫助我...非常感謝!

+0

* f *的意思是*功能*這是正確的 –

+0

這是什麼意思?爲什麼你必須調用'toString'來獲取值?這完全違反直覺。嘗試有一個同時具有可變性和咖喱味的「添加」功能是很奇怪的。 –

+0

@JonasW。正確的功能? – DaXiong1

回答

1

起初,你可以美化整個代碼位:

function add(..arr){ 
    function fun(...args){ 
    arr.push(...args); 
    return fun 
    } 

    fun.toString = function(){ 
    return arr.reduce((total, num) => total + num) 
    }; 
    return fun; 
} 

而當你正確地注意到,記錄的功能完全取決於環境。 Firefox和節點返回函數的代碼,而Chrome並某物像:

out("f" + add.toString()) 

所以我們的ToString函數被調用和一些記錄。有不同的環境之間的一致的行爲,我們可以明確地調用toString:

console.log(add(1)(2)(3).toString()); 

這可以推斷:

console.log("" + add(1)(2)); 
+0

是的,對,這可能是一個很好的解決方案。但我想知道爲什麼一個函數輸出,而不是一個值,並在FF或節點,'console.log(222)'似乎沒有執行... – DaXiong1

+0

@daXiong'火狐和節點返回函數的代碼,而Chrome則是這樣做的:' –

0

如果你想要的是add既可變參數和咖喱(我仍然認爲是奇怪的),只是這樣做:

const add = (...args) => { 
    let accum = args; 
    let f = (...fargs) => { 
    if (!fargs.length) { 
     return accum.reduce((a, b) => { return a + b; }, 0); 
    } else { 
     accum = accum.concat(fargs); 
     return f; 
    } 
    }; 
    return f; 
}; 

add(1,2,3)(); // 6 
add(1)(2,3)(); // 6 
add()(); // 0 

現在你只是調用沒有參數的返回函數來獲取值。你可以玩弄它,使其更具性能(例如,通過在循環中使用.push而不是.concat),但這應該起作用。

+1

...或'accum.push(... fargs)' –

+0

謝謝你,我明白了。這真是個好主意! – DaXiong1