L'affectation à l'argument fn
rend juste cet identificateur pour pointer vers la fonction anonyme, foo
dans la portée externe n'est pas affectée.
Lorsque vous passez un objet en argument, on peut dire "les références sont passées par valeur". L'affectation remplace simplement l'emplacement auquel l'identificateur fn
fait référence.
Voilà comment fonctionne le evaluation strategy en JavaScript.
Juste avant l'affectation dans les fonctions fnChanger
, les deux identifiants, l'foo
mondiale et l'argument fn
, pointez sur le même objet de fonction:
---------------------------------------------
foo -----> |function foo { sys.print('Un changed!'); } |
---------------------------------------------
^
|
fn -------------
Après l'affectation, fn
simplement pointer vers le nouveau fonction:
---------------------------------------------
foo -----> | function foo { sys.print('Unchanged!'); } |
---------------------------------------------
---------------------------------------
fn ------> | function { sys.print('Changed!'); } |
---------------------------------------
Comment pouvez-vous le changer?
Eh bien, en supposant que foo
est une fonction dans la portée globale, vous pourriez faire quelque chose comme ceci:
function fnChanger(obj, name) {
obj[name] = function() { sys.print('Changed!'); };
}
function foo() {
sys.print('Unchanged');
}
fnChanger(this, 'foo');
foo(); // Changed!
ci-dessus fonctionnera parce que dans la fonction fnChanger
, nous avons besoin d'un objet de base et nom de la propriété, les fonctions déclarées dans le contexte d'exécution globale sont liées en tant que propriétés de l'objet global , par conséquent nous pouvons réaffecter sa valeur de cette manière.
La ligne fnChanger(this, 'foo');
doit être exécuté aussi dans la portée globale, il passera la valeur this
(qui fait référence à l'objet global dans ce champ) et un nom de propriété, vous permettant de faire une affectation à l'identifiant GlobalObject.foo
.
Si ce code était à l'intérieur d'une fonction, il n'y a aucun moyen que nous pouvons obtenir un objet de base , parce que dans cette déclaration « Code fonction d'exécution Contexte », fonction (paramètres formels déclarations variables et fonction aussi) sont liés en tant que propriétés d'un objet non accessible, appelé l'objet variable (une chaîne de ces objets variables, constitue la chaîne d'étendue), et si c'était le cas, la seule solution de contournement serait d'utiliser eval
.
Plus d'infos:
Oui, je commençais à soupçonner que ce qui se passe. Merci pour la clarification, et le lien - je n'ai jamais su exactement comment appeler cela ou comment cela a fonctionné. Comment puis-je contourner cela? –
Ok, j'aime cette approche. Pas aussi désordonné que je pensais le faire: passer un objet contenant la fonction à changer. –