Ich habe gerade diese Frage gelesen und wollte die Alias-Methode anstelle der Function-Wrapper-Methode ausprobieren, aber ich konnte sie weder in Firefox 3 oder 3.5beta4 noch in Google Chrome in ihren Debug-Fenstern und in Google Chrome zum Laufen bringen in einer Test-Webseite.
Firebug:
>>> window.myAlias = document.getElementById
function()
>>> myAlias('item1')
>>> window.myAlias('item1')
>>> document.getElementById('item1')
<div id="item1">
Wenn ich es auf eine Webseite stelle, gibt mir der Aufruf von myAlias den folgenden Fehler:
uncaught exception: [Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame :: file:///[...snip...]/test.html :: <TOP_LEVEL> :: line 7" data: no]
Chrome (mit >>> zur Verdeutlichung eingefügt):
>>> window.myAlias = document.getElementById
function getElementById() { [native code] }
>>> window.myAlias('item1')
TypeError: Illegal invocation
>>> document.getElementById('item1')
<div id=?"item1">?
Und auf der Testseite erhalte ich den gleichen "Illegalen Aufruf".
Mache ich etwas falsch? Kann jemand anderes dies reproduzieren?
Seltsamerweise habe ich es auch gerade versucht und es funktioniert in IE8.
Antworten:
Sie müssen diese Methode an das Dokumentobjekt binden. Aussehen:
Wenn Sie einen einfachen Alias ausführen, wird die Funktion für das globale Objekt und nicht für das Dokumentobjekt aufgerufen. Verwenden Sie eine Technik namens Verschlüsse, um dies zu beheben:
Auf diese Weise verlieren Sie nicht den Verweis auf das Originalobjekt.
2012 gibt es die neue
bind
Methode von ES5, mit der wir dies auf schickere Weise tun können:quelle
Ich habe tief gegraben, um dieses spezielle Verhalten zu verstehen, und ich glaube, ich habe eine gute Erklärung gefunden.
Bevor ich
document.getElementById
erkläre , warum Sie keinen Alias verwenden können , werde ich versuchen zu erklären, wie JavaScript-Funktionen / -Objekte funktionieren.Wenn Sie eine JavaScript-Funktion aufrufen, bestimmt der JavaScript-Interpreter einen Bereich und übergibt ihn an die Funktion.
Betrachten Sie folgende Funktion:
Diese Funktion wird im Fensterbereich deklariert. Wenn Sie sie aufrufen, ist der Wert
this
innerhalb der Summenfunktion das globaleWindow
Objekt.Für die 'Summen'-Funktion spielt es keine Rolle, welchen Wert' dies 'hat, da sie nicht verwendet wird.
Betrachten Sie folgende Funktion:
Wenn Sie dave.getAge Funktion aufrufen, sieht der JavaScript - Interpreter , dass Sie getAge Funktion auf dem fordern
dave
Objekt, so setzt siethis
aufdave
und ruft diegetAge
Funktion.getAge()
wird korrekt zurückkehren100
.Möglicherweise wissen Sie, dass Sie in JavaScript den Bereich mithilfe der
apply
Methode angeben können . Lass es uns versuchen.In der obigen Zeile übergeben Sie den Bereich manuell als
bob
Objekt , anstatt JavaScript den Bereich bestimmen zu lassen .getAge
wird jetzt zurückkehren200
, obwohl Sie dachten, Sie hättengetAge
dasdave
Objekt aufgerufen .Was ist der Sinn all dieser Dinge? Funktionen werden "lose" an Ihre JavaScript-Objekte angehängt. ZB kannst du tun
Machen wir den nächsten Schritt.
ageMethod
Ausführung wirft einen Fehler! Was ist passiert?Wenn Sie meine obigen Punkte sorgfältig lesen, werden Sie feststellen, dass die
dave.getAge
Methode mitdave
alsthis
Objekt aufgerufen wurde, während JavaScript den 'Umfang' für dieageMethod
Ausführung nicht bestimmen konnte . Also hat es das globale "Fenster" als "dies" übergeben. Dawindow
keinebirthDate
Eigenschaft vorhanden ist, schlägt dieageMethod
Ausführung fehl.Wie kann ich das beheben? Einfach,
Hat all das Sinn gemacht? Wenn dies der Fall ist, können Sie erklären, warum Sie keinen Alias verwenden können
document.getElementById
:$
heißt mitwindow
asthis
und wenn diegetElementById
Implementierung dies erwartetthis
, schlägtdocument
sie fehl.Um dies zu beheben, können Sie dies erneut tun
Warum funktioniert es in Internet Explorer?
Ich kenne die interne Implementierung
getElementById
in IE nicht, aber ein Kommentar in der jQuery-Quelle (inArray
Methodenimplementierung) besagt, dass in IEwindow == document
. Wenn dies der Fall ist,document.getElementById
sollte Aliasing im IE funktionieren.Um dies weiter zu veranschaulichen, habe ich ein ausführliches Beispiel erstellt. Schauen Sie sich die
Person
Funktion unten an.Für die
Person
obige FunktiongetAge
verhalten sich die verschiedenen Methoden wie folgt.Lassen Sie uns zwei Objekte mit der
Person
Funktion erstellen .Die getAge-Methode ruft direkt das
yogi
Objekt abthis
und gibt es aus100
.Der JavaScript-Interepreter setzt das
window
Objekt aufthis
und unseregetAge
Methode gibt zurück-1
.Wenn wir den richtigen Bereich festlegen, können Sie die
ageAlias
Methode verwenden.Wenn wir ein Objekt einer anderen Person übergeben, wird das Alter trotzdem korrekt berechnet.
Die
ageSmarter
Funktion hat das ursprünglichethis
Objekt erfasst, sodass Sie sich jetzt nicht mehr um die Bereitstellung des richtigen Bereichs kümmern müssen.Das Problem dabei
ageSmarter
ist, dass Sie den Bereich niemals auf ein anderes Objekt festlegen können.Die
ageSmartest
Funktion verwendet den ursprünglichen Bereich, wenn ein ungültiger Bereich angegeben wird.Sie können weiterhin ein anderes
Person
Objekt übergebengetAgeSmartest
. :) :)quelle
Dies ist eine kurze Antwort.
Im Folgenden wird eine Kopie (ein Verweis auf) der Funktion erstellt. Das Problem ist, dass sich die Funktion jetzt auf dem
window
Objekt befindet, als sie auf demdocument
Objekt leben soll.Die Alternativen sind
oder Sie können zwei Aliase verwenden.
quelle
Eine weitere kurze Antwort, nur für Wrapping / Aliasing
console.log
und ähnliche Protokollierungsmethoden. Sie alle erwarten, imconsole
Kontext zu sein.Dies ist nützlich, wenn Sie
console.log
mit einigen Fallbacks umbrechen, falls Sie oder Ihre Benutzer Probleme haben, wenn Sie einen Browser verwenden, der dies (immer) nicht unterstützt . Dies ist jedoch keine vollständige Lösung für dieses Problem, da erweiterte Überprüfungen und ein Fallback erforderlich sind - Ihr Kilometerstand kann variieren.Beispiel mit Warnungen
Dann benutze es wie gewohnt
Wenn Sie es vorziehen, dass Ihre Protokollierungsargumente in ein Array eingeschlossen werden (das tue ich meistens), ersetzen Sie
.apply(...)
durch.call(...)
.Sollte die Arbeit mit
console.log()
,console.debug()
,console.info()
,console.warn()
,console.error()
. Siehe auchconsole
auf MDN .Konsole Feuerwanze
quelle
Neben anderen guten Antworten gibt es die einfache jQuery-Methode $ .proxy .
Sie können Alias wie folgt:
Oder
quelle
$.proxy
auch wirklich ein Wrapper.Sie können eine Funktion für ein vordefiniertes Objekt nicht als "reinen Alias" festlegen. Daher ist das Aliasing, das Sie ohne Umbruch erhalten können, am nächsten, wenn Sie im selben Objekt bleiben:
quelle