2016-03-14 17 views
7

Si verifica uno strano errore quando si tenta di passare Array.from a Array.prototype.map.Array.from TypeError: 0 non è una funzione

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 

Errore completa:

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) 

Cosa sta succedendo?

risposta

9

map chiama il suo callback con tre argomenti: la voce, l'indice e l'oggetto che viene ripetuto. Array.from si aspetta che se gli viene dato un secondo argomento, è una funzione di mappatura, e quindi prova a chiamarlo su ogni "elemento" da cui sta costruendo la matrice. L'indice, 0 alla prima chiamata, non è una funzione, pertanto Array.from non riesce.

dirla in altro modo, l'equivalente di

['test'].map(fn) 

non è

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

ma piuttosto

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

... dove e è l'entrata, i è il suo indice e a è la "matrice" che viene attraversata da map. Poiché i non è una funzione, Array.from non riesce.

È possibile ottenere la stessa cosa con diverse altre funzioni per gli array, come ad esempio forEach, some, ...


Se si esegue questa operazione molto, potreste trovare utile avere una funzione possono utilizzare per filtrare tutti, ma il primo argomento:

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

che può essere utilizzato in questo modo:

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

o forse anche

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

poi

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

Questi sono, ovviamente, due dei peggiori nomi delle funzioni sul pianeta, ma si ottiene l'idea ... :-)

Problemi correlati