Disons que j'ai ces deux fonctions: maintenant, si j'appelle maintenant, je suppose que c'est parce que Code> FOO code> n'est pas transmis à pourquoi ps: j'utilise node.js pour tester tout cela Strip, c'est là que le foo () code>, je vois
inchangé code>, comme attendu. Toutefois, si j'appelle
fnchanger code> d'abord, je vois toujours
inchangé code>: p>
FnCHanger code> par référence, mais je me trompe peut-être. p>
fnChanger code> ne change pas
> FOO code> pour imprimer
modifié! code>?
En outre, comment puis-je obtenir fnchanger code> pour changer
foo code> sans trop de syntaxe désordonnée? P>
sys.print code> vient de. p> p>
4 Réponses :
L'affectation à l'argument Quand vous passez un Objet comme un argument, on peut dire «les références sont transmises par la valeur». L'affectation remplace simplement l'emplacement où l'identifiant C'est comme ça que c'est comment stratégie d'évaluation em> fonctionne dans JavaScript. p> juste avant l'affectation dans les fonctions code> FnCHanger code>, les deux identifiants, les deux identifiants, le Global après l'affectation, Comment pouvez-vous le changer? p> Eh bien, en supposant que ce qui précède fonctionnera car dans la fonction t il ligne Si ce code était à l'intérieur d'une fonction, il n'y a aucun moyen que nous puissions obtenir un < em> l'objet de base em>, car dans ce "contexte d'exécution de code de fonction", les déclarations de fonctions (déclarations variables et paramètres formels de fonction également) sont liées comme propriétés d'un objet non accessible em>, appelé le Objet variable (une chaîne de ces objets variables, forme la chaîne d'étendue), et si c'était le cas, la seule solution de contournement serait d'utiliser Plus d'infos: < / p> fn code> permet simplement à cet identifiant de pointer sur la fonction anonyme,
foo code> dans la portée extérieure n'est pas affecté.
fn code> fait référence à. P>
FOO code> et l'argument
fn code>, pointez sur le même objet de fonction: p>
fn code> signalera simplement la nouvelle fonction: p>
foo < / code> est une fonction de la portée globale, vous pouvez faire quelque chose comme ceci: p>
fnCHanger code>, Nous avons besoin d'un objet objet de base em> et d'un nom de propriété em>, les fonctions déclarées dans le contexte d'exécution global sont liées comme propriétés de l'objet global em>, nous pouvons donc nous pouvons ré-attribuer sa valeur de cette manière. P>
fnCHanger (ceci, 'foo'); code> doit être exécuté également dans la portée globale, il passera la valeur
de cette code> (qui fait référence à l'objet global dans cette portée. ) et un nom de propriété, vous permettant de créer une affectation au
Identificateur code> code>. p>
eval code>. P>
Oui, je commençais à soupçonner que c'est ce qui se passe. Merci pour la clarification et le lien - je n'ai jamais su exactement quoi d'appeler ou comment cela a fonctionné. Comment puis-je me contourner ça?
Ok, j'aime cette approche. Pas aussi désordonné que je pensais faire: passer un objet contenant la fonction à changer.
Comme @CMS a indiqué que vous ne pouvez pas l'affecter dans la fonction en raison de la portée. Cependant, vous pouvez le réaffecter comme ceci comme suit: exemple p> p>
Oui, pensa à cela. Je suis hésitant à le faire par retour dans le code réel, cependant. D'une part, c'est plus propre, mais de l'autre, cela ne correspond pas à ce que la fonction fait réellement.
Il y a un moyen élégant autour de celui-ci explication courte: p>
foo_holder code> à
FnChange code> comme un hachage (ou un tableau). LI>
FOO_HOLDER ["FN"] code> à une nouvelle valeur. Cela changera lorsque la référence interne pointe au lieu de créer une nouvelle référence. Li>
Lorsque vous appelez le FnCHanger (FOO), la variable FN est réellement remplacée avec FOO (). P> mais vous êtes ne pas obtenir le résultat parce que cette fonction n'a jamais été invoquée. Essayez de le renvoyer et d'appeler comme indiqué ci-dessous et que vous allez la réponse requise. P> p> function fnChanger(fn) {
fn = function() {
console.log('Changed!');
}
return fn;
}
function foo() {
console.log('Unchanged');
}
fnChanger(foo)();
foo();