2016-03-14 28 views
7

嘗試將Array.from傳遞給Array.prototype.map時出現奇怪的錯誤。Array.from TypeError:0不是函數

let fn = Array.from.bind(Array); // [Function: bound from] 

fn('test') // [ 't', 'e', 's', 't' ] 

['test'].map(s => fn(s)) // [ [ 't', 'e', 's', 't' ] ] 

['test'].map(fn) // TypeError: 0 is not a function 

完全錯誤:

TypeError: 0 is not a function 
    at Function.from (native) 
    at Array.map (native) 
    at repl:1:10 
    at REPLServer.defaultEval (repl.js:260:27) 
    at bound (domain.js:287:14) 
    at REPLServer.runBound [as eval] (domain.js:300:12) 
    at REPLServer.<anonymous> (repl.js:429:12) 
    at emitOne (events.js:95:20) 
    at REPLServer.emit (events.js:182:7) 
    at REPLServer.Interface._onLine (readline.js:211:10) 

這是怎麼回事?

回答

9

map使用三個參數調用它的回調:條目,索引和被迭代的對象。 Array.from預計如果給它第二個參數,它是一個映射函數,所以試圖在它構建數組的每個「元素」上調用它。第一次調用索引0不是函數,所以Array.from失敗。

換一種方式,

['test'].map(fn) 

相當於不

['test'].map(e => fn(e)) 

而是

['test'].map((e, i, a) => fn(e, i, a)) 

...其中e是入門,i是其索引,a是所穿過的「數組」。由於i不是函數,因此Array.from失敗。

你得到同樣的事情與其他幾個陣列功能,如forEachsome,...


如果你這樣做了很多,你可能會發現它非常有用的功能,你可以用它來過濾所有,但第一個參數:

function passOneArg(f) { 
    return function(a) { return f.call(this, a); }; 
} 

您可以使用這樣的:

['test'].map(passOneArg(fn)) 

或者甚至可能

function limitArgs(f, count) { 
    return function() { 
     return f.apply(this, Array.prototype.slice.call(arguments, 0, count)); 
    }; 
} 

然後

['test'].map(limitArgs(fn, 1)) 

這些,當然,兩個星球上最壞的函數名,但你的想法... :-)

相關問題