2012-10-21 21 views
13

Possible Duplicate:
If Javascript has first-class functions, why doesn’t this work?Alias-Funktion in Javascript

Wenn ich versuche, eine Alias-Funktion für document.getElementById wie unten zu machen:

f = document.getElementById; 

Aber, wenn ich zu nennen versuchen:

var e_fullname = f(“fullname”); 

Es rised wurde ein Fehler: Could not convert JavaScript argument

Und unten ist OK:

var e_fullname = f.call(document, “funname”); 

Können Sie mir sagen, warum?

+2

Sie haben einige ungewöhnliche Zitate. Welchen Editor benutzen Sie? – 0x499602D2

+8

@David echte Programmierer verwenden Word –

+0

Ich glaube nicht, dieses Problem, weil ein Editor. Ich verstehe nur, wie Javascript funktioniert? – vietean

Antwort

20

Es gibt vier Möglichkeiten, den Aufruf einer Funktion:

  1. Funktionsaufruf: f(p1, p2)
  2. Methodenaufruf: obj.f(p1, p2)
  3. Nehmen oder Aufruf Aufruf: f.apply(obj, [p1, p2]), f.call(obj, p1, p2)
  4. Constructor Aufruf: new f(p1, p2)

In all diesen Fällen ist f nur ein Verweis (Zeiger) auf ein Funktionsobjekt (ein Objekt mit einer internen Eigenschaft [[Call]]). Was es in all diesen Fällen anders macht, ist die Art, wie die Funktion aufgerufen wird, und das ist sehr wichtig.

So f ist nur ein Verweis auf das getElementById Objekt, gibt es keinen Unterschied zwischen document.getElementById und someOtherHTMLElement.getElementById; Die Funktion enthält keinen Verweis auf das Objekt, das auf sie verweist.

Wenn Sie eine bestimmte „Besitzer“ Objekt zu binden, verwenden Sie die bind Methode:

var f = document.getElementById.bind(document); 
1

könnten Sie bind

Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function was called.

var f = document.getElementById.bind(document); 

Es verwendet in ES5 eingeführt wurde, so sich bewusst sein Browser noch nicht diese Version von ECMAScript unterstützt!

Als Alternative Sie die proxy Methode von jQuery verwenden könnte, hinzugefügt in Version 1.4

var f = ​$.proxy(document.getElementById, document); 

Oder Sie f als eigene Funktion (dies ist eine ausführlichere Lösung) delcare könnte.

+0

Ich wollte nur darauf hinweisen, dass das JavaScript Version, auf die Sie sich beziehen, ist spezifisch für Mozilla. Wenn Sie andere Browser in Betracht ziehen, ist es hilfreich, auf die ECMAScript-Version zu verweisen. '.bind' wurde in ES5 eingeführt. –

+0

Danke @FelixKling Ich habe es im Text geändert. – clentfort

+1

Das letzte funktioniert nicht, Argumente können nicht direkt so erneut übertragen werden. Sie müssen etwas tun wie 'document.getElementById.apply (Dokument, Array.prototype.slice.call (Argumente));' –

5

getElementById ist eine Methode auf Dokument. Um es aufzurufen, muss der Interpreter den Funktionskörper selbst, das Objekt, auf dem er aufgerufen wird (in Ihrem Fall das Dokument), und die Argumente haben.

Wenn Sie f = document.getElementById tun, kopieren Sie den Funktionskörper, aber nicht das Objekt, auf dem er aufgerufen werden soll.

Wenn Sie dies tun:

f.call(document, “funname”); 

Sie bieten sowohl das Objekt, um es zu rufen, und die Argumente.

Wenn Sie f direkt aufrufen wollen, müssen Sie das Objekt "document" irgendwie dort ablegen. Am einfachsten ist:

var f = function(name){return document.getElementById(name)} 

Dies schafft eine Schließung, die auf den Wert des Dokuments für Sie hält.

Sie können auch bind() verwenden, um dasselbe zu tun.