


Explication détaillée de la portée JS et de la chaîne de portée_Connaissances de base
(1) Portée
La portée d'une variable est la zone de la variable définie dans le code source du programme.
1. La portée lexicale est utilisée en JS
Les variables qui ne sont déclarées dans aucune fonction (var est omise dans une fonction sont également considérées comme globales) sont appelées variables globales (portée globale)
Les variables déclarées dans une fonction ont une portée de fonction et sont des variables locales
Les variables locales ont une priorité plus élevée que les variables globales
var name="un";
fonction test(){
var name="deux";
console.log(nom); //deux
>
test();
Omettre var dans la fonction affectera la variable globale, car elle a en fait été réécrite en variable globale
var name="un";
fonction test(){
name="deux";
>
test();
console.log(nom); //deux
Portée de la fonction, c'est-à-dire que la fonction est l'unité de base d'une portée js n'a pas de portée au niveau du bloc comme c/c, comme if for, etc.
fonction test(){
pour(var i=0;i<10;i ){
Si(i==5){
var nom = "un";
>
>
console.log(nom); //un
>
test(); //Comme il s'agit d'une portée au niveau de la fonction, vous pouvez accéder à name="one"
Bien sûr, des fonctions d'ordre supérieur sont également utilisées dans js, qui peuvent en fait être comprises comme des fonctions imbriquées
fonction test1(){
var nom = "un";
Fonction de retour (){
console.log(nom);
>
>
test1()();
Après test1(), la fonction externe sera appelée et une fonction interne sera renvoyée. Ensuite, continue(), et la fonction interne sera appelée et exécutée en conséquence, donc "one"
sera affiché.Les fonctions imbriquées impliquent des fermetures, dont nous parlerons plus tard. Ici, la fonction interne peut accéder au nom de variable déclaré dans la fonction externe, ce qui implique le mécanisme de chaîne de portée
2. Déclaration en JS à l'avance
La portée de la fonction en js signifie que toutes les variables déclarées dans la fonction sont toujours visibles dans le corps de la fonction. De plus, la variable peut être utilisée avant d'être déclarée. Cette situation est appelée levage
.astuce : La déclaration à l'avance est effectuée lorsque le moteur js est pré-compilé. Le phénomène de déclaration à l'avance se produit avant l'exécution du code
.Par exemple
var name="un";
fonction test(){
console.log(nom); //non défini
var name="deux";
console.log(nom); //deux
>
test();
Ce qui précède produit l'effet suivant
var name="un";
fonction test(){
nom de la variable ;
console.log(nom); //non défini
name="deux";
console.log(nom); //deux
>
test();
Essayez à nouveau de supprimer var ? C'est le nom au sein de la fonction qui est devenue une variable globale, elle n'est donc plus indéfinie
var name="un";
fonction test(){
console.log(nom); //un
name="deux";
console.log(nom); //deux
>
test();
3. Il convient de noter qu'aucun des paramètres mentionnés ci-dessus n'est réussi. Que se passe-t-il si le test a des paramètres ?
test de fonction (nom) {
console.log(nom); //un
name="deux";
console.log(nom); //deux
>
var nom = "un";
test(nom);
console.log(nom); // un
Comme mentionné précédemment, les types de base sont transmis par valeur, donc le nom transmis au test n'est en fait qu'une copie. Cette copie est effacée après le retour de la fonction.
Ne pensez pas que name="two" dans la fonction change le nom global, car ce sont deux noms indépendants
(2) Chaîne de portée
Les fonctions avancées mentionnées ci-dessus impliquent une chaîne de portée
fonction test1(){
var nom = "un";
Fonction de retour (){
console.log(nom);
>
>
test1()();
1. Présentez un grand paragraphe pour expliquer :
Chaque élément de code JavaScript (code global ou fonction) est associé à une chaîne de portées.
Cette chaîne de portée est une liste ou une liste chaînée d'objets. Ce groupe d'objets définit les variables "dans la portée" dans ce code.
Lorsque js a besoin de trouver la valeur de la variable x (ce processus est appelé résolution de variable), il commencera à partir du premier objet de la chaîne. Si cet objet a un attribut nommé x, alors la valeur de cet attribut sera. utilisé directement. S'il n'y a pas d'attribut nommé x dans le premier objet, js continuera à rechercher l'objet suivant dans la chaîne. Si le deuxième objet n’a toujours pas d’attribut nommé x, il continuera à chercher le suivant, et ainsi de suite. Si aucun objet dans la chaîne de portée ne contient l'attribut x, alors on considère que x n'existe pas dans la chaîne de portée de ce code, et finalement une exception ReferenceError est levée.
2. Exemple de chaîne de portée :
Dans le code de niveau supérieur de js (c'est-à-dire le code qui n'inclut aucune définition de fonction), la chaîne de portée est constituée d'un objet global.
Dans un corps de fonction qui ne contient pas d'imbrication, il y a deux objets sur la chaîne de portée. Le premier est l'objet qui définit les paramètres de la fonction et les variables locales, et le second est l'objet global.
Dans un corps de fonction imbriqué, il y a au moins trois objets dans la portée.
3. Règles de création de chaîne de portée :
Lorsqu'une fonction est définie (notez qu'elle démarre lorsqu'elle est définie), elle enregistre en fait une chaîne de portées.
Lorsque cette fonction est appelée, elle crée un nouvel objet pour stocker ses paramètres ou variables locales, ajoute l'objet à cette chaîne de portée et crée une nouvelle représentation plus longue de la portée appelant la fonction.
Pour les fonctions imbriquées, la situation change à nouveau : à chaque fois que la fonction externe est appelée, la fonction interne sera à nouveau redéfinie. Car chaque fois qu’une fonction externe est appelée, la chaîne de portées est différente. Les fonctions internes doivent être subtilement différentes à chaque fois qu'elles sont définies - le code de la fonction interne est le même à chaque fois que la fonction externe est appelée, et la chaîne de portée associée à ce code est également différente.
(astuce : Comprenez bien les trois points ci-dessus et souvenez-vous-en. Il est préférable de le dire avec vos propres mots, sinon vous devrez le mémoriser, car l'intervieweur vous demandera directement : Veuillez décrire la chaîne de portée.. . )
Un exemple pratique de chaînage de portée :
var name="un";
fonction test(){
var name="deux";
fonction test1(){
var name="trois";
console.log(nom); //trois
>
fonction test2(){
console.log(nom); // deux
>
test1();
test2();
>
test();
Ce qui précède est une fonction imbriquée, il devrait donc y avoir trois objets dans la chaîne de portée
Ensuite, lors de l'appel, vous devez trouver la valeur du nom, recherchez simplement
Lorsque test1() est appelé avec succès, l'ordre est test1()->test()-> Parce que la valeur trois de name est trouvée sur test1(), la recherche est terminée et renvoie <.> Lorsque test1() est appelé avec succès, l'ordre est test2()->test()->fenêtre d'objet globale Parce que la valeur de name n'est pas trouvée sur test2(), nous la recherchons dans test(. ) et trouvez-le Si la valeur de name est deux, la recherche sera terminée et renverra
.
Un autre exemple est que parfois nous faisons des erreurs et sommes souvent trompés lors des entretiens.
ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
http://www.w3.org/1999/xhtml">
函數buttonInit(){
for(var i=1;i var b=document.getElementById("button" i);
b.addEventListener("click",function(){
警報(「按鈕」i); // 都是 Button4
},假);
}
}
window.onload=buttonInit;
腳本>
頭>
按鈕1按鈕>
按鈕2按鈕>
Button3
身體>
為什麼?
根據作用域鏈中指標的查找規則:
b.addEventListener("click",function(){
警報(「按鈕」i);
},假);
這裡有一個函數,它是匿名函數,既然是函數,那麼在域鏈上有一個作用對象,這個函數裡邊使用到了變數i,它自然會在作用域上找到它。
查找順序是這個匿名函數 --> 外部的函數buttonInit() --> 全域物件window
匿名函數中找不到i,自然找到了buttonInit(),ok,在for中找到了,
今年註冊事件已經結束了,以為它會一個把我放下來,因為函數作用域內的變數對作用域內是一直可見的,也就是說會保持到最後的狀態
當匿名函數要使用i的時候,註冊事件完了,i已經變成了4,所以都是Button4
那要怎麼解決呢?
給它傳值進去吧,每次循環時,再使用一個匿名函數,把裡邊的i傳進去,匿名函數的規則如程式碼
ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
http://www.w3.org/1999/xhtml">
函數buttonInit(){
for(var i=1;i (函數(data_i){
var b=document.getElementById("button" data_i);
b.addEventListener("click",function(){
Alert("按鈕" data_i);
},假);
})(i);
}
}
window.onload=buttonInit;
腳本>
頭>
按鈕1按鈕>
按鈕2按鈕>
Button3
身體>
這樣就可以Button1..2..3了
4.上述就是作用域鏈的基本描述,另外,with語句可用於臨時拓展作用域鏈(不建議使用with)
語法形如:
與(對象)
聲明
這個with語句,將物件加入到作用域鏈的頭部,然後執行語句,最後把作用域鏈恢復到原始狀態
簡單用法:
例如給表單中各項目的值賦值
一般我們可以這樣直接
var f = document.forms[0];
f.name.value = "";
f.age.value = "";
f.email.value = "";
引入with後(因為使用with會產生一系列問題,所以還是使用上面那張形式吧)
with(document.forms[0]){
f.name.value = "";
f.age.value = "";
f.email.value = "";
}
另外,假如 一個物件o具有x屬性,o.x = 1;
那麼使用
with(o){
x = 2;
}
就可以轉換成 o.x = 2;
假如o沒有定義屬性x,它的功能就只是相當於 x = 2; 一個全域變數罷了。
因為with提供了一種讀取o的屬性的快捷方式,但他並不能創建o本身沒有的屬性。
以上所述就是本文的全部內容了,希望能夠對大家學習javascript有所幫助。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

typedef struct est utilisé en langage C pour créer des alias de type de structure afin de simplifier l'utilisation des structures. Il crée un alias pour un nouveau type de données sur une structure existante en spécifiant l'alias de la structure. Les avantages incluent une lisibilité améliorée, la réutilisation du code et la vérification du type. Remarque : La structure doit être définie avant d'utiliser un alias. L'alias doit être unique dans le programme et valide uniquement dans le périmètre dans lequel il est déclaré.

Les exceptions de valeur attendue des variables en Java peuvent être résolues en : initialisant les variables ; en utilisant des valeurs par défaut ; en utilisant des contrôles et des affectations et en connaissant la portée des variables locales ;

Les avantages des fermetures JavaScript incluent le maintien d'une portée variable, l'activation du code modulaire, l'exécution différée et la gestion des événements ; les inconvénients incluent les fuites de mémoire, la complexité accrue, la surcharge de performances et les effets de chaîne de portée.

La directive de préprocesseur #include en C++ insère le contenu d'un fichier source externe dans le fichier source actuel, en copiant son contenu à l'emplacement correspondant dans le fichier source actuel. Principalement utilisé pour inclure des fichiers d'en-tête contenant les déclarations nécessaires dans le code, telles que #include <iostream> pour inclure des fonctions d'entrée/sortie standard.

Cycle de vie des pointeurs intelligents C++ : Création : Les pointeurs intelligents sont créés lors de l'allocation de mémoire. Transfert de propriété : Transférer la propriété via une opération de déménagement. Libération : la mémoire est libérée lorsqu'un pointeur intelligent sort de la portée ou est explicitement libéré. Destruction d'objet : lorsque l'objet pointé est détruit, le pointeur intelligent devient un pointeur invalide.

Peut. C++ autorise les définitions et les appels de fonctions imbriquées. Les fonctions externes peuvent définir des fonctions intégrées et les fonctions internes peuvent être appelées directement dans la portée. Les fonctions imbriquées améliorent l'encapsulation, la réutilisabilité et le contrôle de la portée. Cependant, les fonctions internes ne peuvent pas accéder directement aux variables locales des fonctions externes et le type de valeur de retour doit être cohérent avec la déclaration de la fonction externe. Les fonctions internes ne peuvent pas être auto-récursives.

Dans Vue, il existe une différence de portée lors de la déclaration de variables entre let et var : Scope : var a une portée globale et let a une portée au niveau du bloc. Portée au niveau du bloc : var ne crée pas de portée au niveau du bloc, let crée une portée au niveau du bloc. Redéclaration : var permet de redéclarer les variables dans la même portée, ce qui n'est pas le cas.

En JavaScript, les types de pointage de this incluent : 1. Objet global ; 2. Appel de fonction ; 3. Appel de constructeur 4. Gestionnaire d'événements 5. Fonction de flèche (héritant de this). De plus, vous pouvez définir explicitement ce que cela désigne à l'aide des méthodes bind(), call() et apply().
