Peut-être que de nombreuses personnes ont rencontré une confusion sur la méthode de livraison des paramètres de fonction dans le processus d'apprentissage du JavaScript Dans un esprit d'analyse approfondie, je vais partager avec vous un tutoriel. à propos de JavaScript. Connaissance des appels de fonctions, amis intéressés, apprenons ensemble
Définition
De nombreuses personnes peuvent avoir rencontré des paramètres de fonction au cours du processus d'apprentissage. Javascript Confus sur la méthode de transmission, dans un esprit d'analyse approfondie, je souhaite trouver quelques réponses dans le code source. Mais avant de faire cela, je dois d'abord clarifier quelques concepts. Abandonnez les noms inhérents de passage de valeur, référence passage, etc., et revenez à l'anglais :
appel par référence && appel par valeur && appel par partage
Ils sont ce que nous entendons par passage de référence et passage de valeur en C++. La troisième est plus confuse. L'explication officielle est que reçoit la copie de la référence à l'objet . Permettez-moi de l'expliquer en termes simples :
L'objet peut être compris comme une collection de clé L'objet fait référence aux données pointées par la clé (je ne préciserai pas s'il s'agit d'une clé). implémentation de pointeur ou une implémentation de référence C++). Ce que la fonction reçoit est une copie d'une variable . La variable contient une référence à l'objet et est passée par valeur.
Ensuite, il est évident que le paramètre de type object que nous recevons lors du passage des paramètres de fonction est en fait une copie du paramètre réel, il n'est donc pas possible de changer directement le pointeur du paramètre de type ; parce que l'objet lui-même Les clés sont toutes des références, il est donc possible de modifier le pointeur de la clé.
Preuve
Quelques morceaux de code simples peuvent le prouver
Code 1 : La fonction peut modifier les données pointées à par clé
let func = obj => { obj.name = 'Dosk' }; let obj = {name : 'Alxw'}; console.log(obj); //{ name: 'Alxw' } func(obj) console.log(obj); //{ name: 'Dosk' }
Code 2 : La fonction ne peut pas modifier obj
let func = obj => { obj = {} }; let obj = {name : 'Alxw'}; console.log(obj); //{ name: 'Alxw' } func(obj) console.log(obj); //{ name: 'Alxw' }
Code 3 : Les résultats obj interne et externe === sont égaux
let def = {name : 'Alxw'}; let func = obj => { console.log(obj === def) }; func(def); //true
Donc, le troisième morceau de code Vous avez peut-être des questions Puisque obj est une copie de def, pourquoi l'opération === peut-elle toujours être vraie ? Cela ne signifie-t-il pas que l'opération === compare l'adresse dans la mémoire de l'objet ? S'il s'agit d'une copie, elle devrait être fausse ?
Retournons donc au code source de Google V8 pour voir cela.
Au cœur de Google V8
Jetons un coup d'œil à la partie du code d'opération strictement égal dans le code source :
bool Object::StrictEquals(Object* that) { if (this->IsNumber()) { if (!that->IsNumber()) return false; return NumberEquals(this, that); } else if (this->IsString()) { if (!that->IsString()) return false; return String::cast(this)->Equals(String::cast(that)); } else if (this->IsSimd128Value()) { if (!that->IsSimd128Value()) return false; return Simd128Value::cast(this)->Equals(Simd128Value::cast(that)); } return this == that; }
Il semble que cela devrait être le dernier cas. Théoriquement, si def et obj sont des objets différents, alors false devrait être renvoyé. Cela ne renverse-t-il pas ce qui précède ? En fait non, une chose est ignorée, c'est-à-dire que lors de l'instanciation d'un objet en interne, Google V8 lui-même est une instanciation dynamique, et nous savons que dans les langages compilés, l'instanciation dynamique ne peut être effectuée que sur la mémoire tas, c'est-à-dire que seuls les pointeurs peuvent être utilisé. La preuve de cette conclusion implique l'implémentation de Local, Handle et autres class Je pense que c'est trop gênant. Il existe un moyen simple de le prouver, qui est de <. 🎜> recherchez le code source Tous les lieux où sont appelés sont transmis directement sans effectuer l'opération d'adresse. Object::StrictEquals
Redéfinition
Je pense pouvoir réexpliquer l'appel en partageant ici : En effet, il est passé par valeur, mais le contenu contient le pointeur d'Objet, et ce pointeur n'est pas modifiable. Il est partagé par plusieurs variables.Une autre preuve simple
Allez, regarde le code sourceV8_DEPRECATE_SOON("Use maybe version", Local<Value> Call(Local<Value> recv, int argc, Local<Value> argv[])); V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context, Local<Value> recv, int argc, Local<Value> argv[]);
interface est utilisée. Il arrive que le code de version que j'ai vu contienne une grande partie de ce code qui est sur le point d'être obsolète. L'accent est mis sur la deuxième interface, qui est la seule interface appelante de la fonction. L'intérieur appellera éventuellement la copie binaire du C++, il peut donc être facilement prouvé qu'il est passé par valeur. Local<Value>
peut être le point clé
N'oubliez pas, les variables que nous définissons sont toutes sous la forme de, donc elles Les objets sont partagés entre objets. Ce que nous appelons des variables en Javascript ne font pas directement référence à des instances d'Objet !!!Handle<Object>
La dernière
Bref, il peut être difficile de comprendre voire contenir des erreurs, mais il est important de pouvoir en déterminer les caractéristiques au niveau du langage Javascript.
Ce qui précède est l'appel de fonction en Javascript présenté par l'éditeur. J'espère qu'il vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. . Je tiens également à vous remercier tous pour votre soutien au site Web de Script House !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!