Die Zuweisung an das fn
Argument macht nur, dass der Bezeichner auf die anonyme Funktion zeigt, foo
im äußeren Bereich ist nicht betroffen.
Wenn Sie ein Objekt als Argument übergeben, kann man sagen "Referenzen werden nach Wert übergeben". Die Zuweisung ersetzt nur den Standort, auf den sich der Bezeichner fn
bezieht.
So funktioniert die evaluation strategy in JavaScript.
Kurz vor der Zuordnung in den fnChanger
Funktionen, die beiden Kennungen, die globalen foo
und das fn
Argument, auf das gleiche Funktionsobjekt:
---------------------------------------------
foo -----> |function foo { sys.print('Un changed!'); } |
---------------------------------------------
^
|
fn -------------
Nach der Zuweisung wird fn
zeigen Sie einfach auf den neuen Funktion:
---------------------------------------------
foo -----> | function foo { sys.print('Unchanged!'); } |
---------------------------------------------
---------------------------------------
fn ------> | function { sys.print('Changed!'); } |
---------------------------------------
Wie können Sie es ändern?
Nun, unter der Annahme, dass foo
ist eine Funktion im globalen Bereich, können Sie etwas tun könnten:
function fnChanger(obj, name) {
obj[name] = function() { sys.print('Changed!'); };
}
function foo() {
sys.print('Unchanged');
}
fnChanger(this, 'foo');
foo(); // Changed!
Die oben funktioniert, weil in der fnChanger
Funktion benötigen wir ein Basisobjekt und eine Eigenschaftsname, Funktionen, die im globalen Ausführungskontext deklariert sind, werden als Eigenschaften des globalen Objekts gebunden, daher können wir seinen Wert auf diese Weise neu zuweisen.
Die Linie fnChanger(this, 'foo');
sollte auch im globalen Rahmen ausgeführt wird, wird es den this
Wert übergeben (die in diesem Umfang auf das globale Objekt bezieht) und einen Eigenschaftsnamen, in dem Sie eine Zuordnung zu der GlobalObject.foo
Kennung zu machen.
Wenn dieser Code in einer Funktion war, gibt es keine Möglichkeit, ein Basisobjekt, weil in dieser „Funktionscodeausführung Context“ erhalten kann, Funktionsdeklarationen (Variablendeklarationen und Funktion auch formale Parametern) als Eigenschaften gebunden eines nicht zugreifbaren Objekts, genannt das Variable Object (eine Kette dieser Variablenobjekte, bildet die Umfangskette), und wenn dies der Fall wäre, wäre die einzige Umgehungslösung die Verwendung von eval
.
Weitere Informationen:
Ja, ich fing an, das ist zu vermuten, was geschieht. Danke für die Klärung und den Link - ich wusste nie genau, wie ich das nennen soll oder wie es funktioniert. Wie kann ich das umgehen? –
Ok, ich mag diesen Ansatz. Nicht so unordentlich, wie ich es mir vorgestellt habe: ein Objekt übergeben, das die zu ändernde Funktion enthält. –