L'enthousiasme pour le travail n'a pas été très élevé depuis le début de la nouvelle année, et je suis dans un état d'inactivité ces jours-ci. Je ne veux pas me lever le matin et je ne veux pas aller travailler quand je me lève. Évidemment, mon enthousiasme au travail était encore très élevé avant les vacances et j'avais réfléchi au petit projet de programme. Cependant, après mon retour de vacances, mon style de travail était complètement différent. J'ai l'impression d'avoir un syndrome sévère de l'après-vacances. Heureusement, j’ai écrit quelques articles pour montrer que cette semaine n’a pas été complètement perdue. Cet article va vous présenter les objets variables.
En JavaScript, nous devons inévitablement déclarer des variables et des fonctions, mais comment l'analyseur JS trouve-t-il ces variables ? Nous devons également mieux comprendre le contexte d’exécution.
Dans l'article précédent, nous savions déjà que lorsqu'une fonction est appelée (activée), un nouveau contexte d'exécution est créé. Le cycle de vie d'un contexte d'exécution peut être divisé en deux étapes.
1. Phase de création
Dans cette phase, le contexte d'exécution créera des objets variables, établira des chaînes de portée et déterminera le point de cela
2. Phase d'exécution du code
Une fois la création terminée, l'exécution du code commencera à ce moment-là, l'affectation des variables, la référence de fonction et d'autres exécutions de code seront terminées.
De là, nous pouvons voir qu'il est extrêmement important de comprendre le contexte d'exécution en détail, car il implique des objets variables, des chaînes de portée, ceci, etc. Beaucoup de gens ne le font pas comprenez-le, mais Mais c'est un concept extrêmement important, il est donc lié à la question de savoir si nous pouvons vraiment comprendre JavaScript. Nous les résumerons un par un en détail dans les articles suivants. Ici, nous nous concentrons d'abord sur la compréhension des objets variables.
Objet variable
La création d'un objet variable passe par les processus suivants dans l'ordre.
1.Créer un objet arguments. Vérifiez les paramètres dans le contexte actuel et établissez les attributs et les valeurs d'attribut sous l'objet.
2. Vérifiez la déclaration de fonction du contexte actuel, c'est-à-dire la fonction déclarée à l'aide du mot-clé function. Créez un attribut avec le nom de la fonction dans l'objet variable et la valeur de l'attribut est une référence à l'adresse mémoire où se trouve la fonction. Si l'attribut de nom de fonction existe déjà, l'attribut sera remplacé par la nouvelle référence.
3. Vérifiez la déclaration de variable dans le contexte actuel. Chaque fois qu'une déclaration de variable est trouvée, créez un attribut avec le nom de la variable dans l'objet variable et la valeur de l'attribut n'est pas définie. Si l'attribut du nom de la variable existe déjà, afin d'éviter que la fonction du même nom ne soit modifiée en non définie, il sera directement ignoré et la valeur de l'attribut d'origine ne sera pas modifiée.
Selon cette règle, comprendre la promotion variable devient très simple. Bien que la promotion variable soit mentionnée dans de nombreux articles, beaucoup de gens ne peuvent vraiment pas dire de quoi il s'agit exactement. À l'avenir, utilisez le processus de création d'objets variables pour expliquer la promotion variable à l'intervieweur afin d'assurer une amélioration instantanée.
D'après les règles ci-dessus, nous voyons que les déclarations de fonctions ont une priorité plus élevée que les déclarations var. Afin d'aider chacun à mieux comprendre les objets variables, nous en discuterons avec quelques exemples simples.
// demo01 function test() { console.log(a); console.log(foo()); var a = 1; function foo() { return 2; } } test();
Dans l'exemple ci-dessus, nous commençons à comprendre directement à partir du contexte d'exécution de test(). Lorsque test() est exécuté dans la portée globale, le contexte d'exécution de test() commence à être créé. Afin de faciliter la compréhension, nous utilisons le formulaire suivant pour exprimer
创建过程 testEC = { // 变量对象 VO: {}, scopeChain: {}, this: {} } // 因为本文暂时不详细解释作用域链和this,所以把变量对象专门提出来说明 // VO 为 Variable Object的缩写,即变量对象 VO = { arguments: {...}, foo: <foo reference> // 表示foo的地址引用 a: undefined }
Avant d'entrer dans la phase d'exécution, les attributs de l'objet variable ne sont pas accessibles ! Mais après être entré dans la phase d'exécution, l'objet variable est transformé en objet actif et les propriétés qu'il contient sont accessibles, puis les opérations de la phase d'exécution commencent.
De cette façon, si on vous demande lors de l'entretien quelle est la différence entre les objets variables et les objets actifs, vous pouvez y répondre librement. Ce sont en fait le même objet, mais ils sont dans une exécution différente. contextes.
// 执行阶段 VO -> AO // Active Object AO = { arguments: {...}, foo: <foo reference>, a: 1 }
Par conséquent, dans l'exemple demo1 ci-dessus, la séquence d'exécution devient comme ceci
function test() { function foo() { return 2; } var a; console.log(a); console.log(foo()); a = 1; } test();
Prenons un autre exemple pour consolider notre compréhension.
// demo2 function test() { console.log(foo); console.log(bar); var foo = 'Hello'; console.log(foo); var bar = function () { return 'world'; } function foo() { return 'hello'; } } test();
// 创建阶段 VO = { arguments: {...}, foo: <foo reference>, bar: undefined } // 这里有一个需要注意的地方,因为var声明的变量当遇到同名的属性时,会跳过而不会覆盖
// 执行阶段 VO -> AO VO = { arguments: {...}, foo: 'Hello', bar: <bar reference> }
Vous devez combiner les connaissances ci-dessus et comparer soigneusement les modifications apportées à l'objet variable de la phase de création à la phase d'exécution dans cet exemple. Si vous l'avez compris, expliquez. que tout ce qui concerne l'objet variable est Ce n'est plus difficile pour vous.
Objet variable de contexte global
Prenons le navigateur comme exemple, l'objet global est window.
Le contexte global a une place particulière, son objet variable est l'objet window. Cette particularité s'applique également à ce point, qui pointe également vers window.
// 以浏览器中为例,全局对象为window // 全局上下文 windowEC = { VO: window, scopeChain: {}, this: window }
De plus, le cycle de vie du contexte global est cohérent avec le cycle de vie du programme. Tant que le programme ne se termine pas, comme par exemple en fermant la fenêtre du navigateur, le contexte global sera toujours. exister. Tous les autres contextes ont un accès direct aux propriétés du contexte global.