2015-10-08 2 views
6

I ein Array haben, wie das Verfahren auf Prototyp als Rückruf Array.map definiert passieren

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

und ich möchte die Räume von jedem von dem Element aus dem Array trim.

Es kann mit Array.map als

arr.map(function(el) { 
    return el.trim(); 
}); 

Ich bin neugierig auf das Bestehen der trim/toLowerCase Funktion direkt an den map als Callback-Funktion, wie arr.map(Math.max.apply.bind(Math.max, null)); getan werden, um das maximale Element erhalten von jedem Sub-Array oder arr.map(Number); um jedes Element auf Number zu setzen.

Ich habe

versucht
arr.map(String.prototype.trim.apply); 

aber es wirft Fehler

Uncaught TypeError: Function.prototype.apply was called on undefined, which is a undefined and not a function

Ich erwarte, dass String.prototype.trim.apply sollte für jedes Element in der Anordnung mit dem auf das Element von Array-Set-Kontext aufgerufen werden (weitergegeben an apply);

Ich habe auch verschiedene Kombinationen von apply, call und bind mit keinem Erfolg ausprobiert.

  1. Warum die Funktion auf Prototyp kann nicht referenziert werden, wenn map mit
  2. Wie Funktion kann als Parameter auf map
+0

Ich bin verwirrt, warum arr.map (Funktion ... arbeitet während arr.map (String ... wirft "arr nicht definiert ist." – djechlin

+0

In Firefox heißt es "TypeError:' Function.prototype.apply' genannt inkompatibel 'undefined'". – Xufox

+0

var f = String.prototype.trim.call; f ('3'); wirft einen Fehler, obwohl String.prototype.trim .call ('3') funktioniert und typeof f === 'function'. Keine Ahnung warum. – djechlin

Antwort

5
arr.map(String.prototype.trim.call.bind(String.prototype.trim)); 

call verwendet this intern übergeben werden, die zeigen muss an die trim Funktion in diesem Fall ordnungsgemäß zu arbeiten. Wenn Sie einfach String.prototype.trim.call übergeben, wird call ungebunden an eine beliebige Methode gelassen, was dazu führt, dass der Wert this auf window verweist.

It works, but when used apply instead of call it throws error, arr.map(String.prototype.trim.apply.bind(String.prototype.trim));

Das Problem ist, dass map 2 Argumente übergeben werden, die Position und den Index. Daher ruft es so etwas wie 'String.prototype.trim.apply('test', 0) auf, was fehlschlägt, da das zweite Argument ein Array sein muss.

one more thing [' A ', ' B ', 'c'].map(String.prototype.trim.call.bind(String.prototype.toLowerCase));, in this, I've used trim.call and passed toLowerCase as context then why we need trim here, why trim is not called

Wenn call.bind mit dem Pfad, den Sie die call Funktionsreferenz wird irrelevant für den Zugriff gewählt haben. Die Funktion, die aufgerufen wird, ist diejenige, die gebunden ist.

Wenn Sie Funktionen komponieren wollen zusammen benötigen Sie einen anderen Ansatz:

var call = Function.prototype.call, 
    trim = call.bind(String.prototype.trim), 
    toLowerCase = call.bind(String.prototype.toLowerCase), 
    trimAndLowerCase = pipelineFrom(trim, toLowerCase); 

[' TeST '].map(trimAndLowerCase); 

function pipelineFrom(fn1, fn2) { 
    return function (val) { 
     return fn2(fn1(val)); 
    }; 
} 

jedoch an diesem Punkt sind Sie besser dran mit:

arr.map(function (val) { 
    return val.trim().toLowerCase(); 
}); 
+0

Es funktioniert, aber wenn 'apply' anstelle von' call' verwendet wird, wird der Fehler 'arr.map (String.prototype. trim.apply.bind (String.prototype.trim)); ' – Tushar

+0

noch eine Sache' ['A', 'B', 'c']. map (String.prototype.trim.call.bind (String.prototype. toLowerCase)); ', in diesem habe ich' trim verwendet. call 'und passier' toLowerCase' als Kontext, warum brauchen wir 'trim' hier, warum trim heißt nicht – Tushar

+1

@Tushar' trim' wird nicht aufgerufen, weil du es nur als Abkürzung benutzt hast, um einen Verweis auf den 'call' zu bekommen Funktion. Die Funktion, die aufgerufen wird, ist 'toLowerCase'. Zum Beispiel könnten Sie 'Function.prototype.call.bind (String.prototype.toLowerCase)' gemacht haben und es würde auch funktionieren. Wie Sie einen Verweis auf die Funktion "Anruf" erhalten, wird irrelevant. – plalx

2

Dies funktioniert, ist es sicher, lang ist -winded aber:

var t = String.prototype.trim.call.bind(String.prototype.trim); 
arr.map(t); 

Weil es langatmig ist es blog posts ein d modules gewidmet zum Entkommen, das ist, was Sie hier zu tun versuchen.

ich ask about this hier einmal war ...

+0

Es funktioniert, aber wenn "Apply" anstelle von "Call" verwendet wird, wird der Fehler "arr.map (String.prototype.trim.apply.bind (String.prototype.trim));' – Tushar

+0

eine weitere Sache "[' A ',' B ',' c '. Map (String.prototype.trim.call.bind (String.prototype.toLowerCase)); ', in diesem habe ich' trim.call' verwendet und 'toLowerCase übergeben 'Als Kontext brauchen wir dann' trim', warum trim nicht heißt – Tushar

Verwandte Themen