Maison > Article > interface Web > Vous guidez étape par étape pour comprendre les variables et l'environnement lexical en Javascript
En fait, je pense que la chose importante au cœur de Javascript n'est pas la syntaxe avancée étendue de l'ancienne version, comme l'affectation de déstructuration, la syntaxe d'expansion et les paramètres restants (enfin... bien que ce soit effectivement très 666), mais bien les utiliser est en fait basé sur votre compréhension des variables (les gens ne connaissent souvent pas la différence entre une lvalue ou une rvalue. Pour cette raison, je pense comprendre une). Javascript doit commencer par le plus basique, c'est-à-dire comprendre ce que sont les variables.
En fait, cet article n'est pas tout à fait basique. Il repose tout de même sur une certaine compréhension de Javascript, du moins une certaine compréhension des objets. Commençons.
Variables et données
Que sont les variables ?
Plus la réponse à la question est simple, plus elle est surprenante. Les réponses de la plupart des gens sont liées à lavaleur ; zones (terme espace mémoire) , lorsque le programme Javascript est en cours d'exécution, la zone de stockage (terme est espace mémoire) peut enregistrer tout ce dont nous avons besoin, du code, des données... etc. Ensuite, les données stockées dans la variable peuvent être grossièrement divisées en deux catégories : type original (identique au type de base) et type de référence ; 🎜> C'est une valeur. Lorsque vous mettez une valeur dans une variable , la valeur redevient une donnée. Javascript est similaire aux autres langages. Les variables doivent également être déclarées pour exister réellement. La variable déclarée est appelée instanciation Lorsqu'une variable se voit attribuer une valeur (la valeur par défaut n'est pas définie), cela s'appelle C'est l'
initialisation des variables variables qui sont juste instanciées mais non initialisées sont dans l'état non initialisé. Par exemple : let a = a ; // (*)
console.log(a);
// ReferenceError: can't access lexical declaration `a' before initialization
signale parfaitement une erreur (à la position de la marque
ne peut pas utiliser
sans initialiser cette variable. Ceci est différent des variables de bas niveau telles que C++. En fait, ce phénomène porte un nom très fantaisiste en Javascript :Temporary Dead Zone(*)
. J'en expliquerai les raisons dans quelques chapitres. (J'ai oublié de mentionner qu'une déclaration de variable a aussi besoin d'un nom. Le terme s'appelle un identifiant. Je ne pense pas que cela affectera quoi que ce soit si je ne l'ajoute pas...) Mais une autre particularité de Javascript est qu'il peut
les variables déclarées par
, et Javascript attribuera automatiquement une valeur non définie aux variables déclarées par. var
Par exemple : var a = a;console.log(a); // undefined.
Regardez, ils sont évidemment similaires, mais les résultats sont complètement différents. var
Mais c'est en fait inutile. Voir le code ci-dessous :
var a = a;console.log(a+2); // NaNLe résultat est
, ce qui est un résultat que nous ne voulons pas du tout. Lorsque
si le calcul mathématique échoue
non numériqueNaN
, représenté par . Mais ce qui est plus intéressant, c'est que si vous utilisez pour vérifier le type :
typeof NaN ; // number
NaN
nous indique que ce typeof
TMDNaN
est un numéro numérique. Il y a beaucoup de choses inexplicables à propos de Javascript, mais nous devrions arrêter de taquiner JavaScript et commencer à l'étudier sérieusement.
Types et stockage
Javascript a un total de 7 types primitifs et 1 type de référence, comme suit :
Type primitif1, nombre
3, booléen
4, symbole
5, bigint
6. non défini
7. null
Type de référence :objet
(J'utilise des lettres minuscules ici, parce que
renvoie les lettres minuscules) et typeof
le résultat est :
function sayHello(){ console.log('hello the world'); } console.log(typeof sayHello); // function console.log(typeof null); // object
typeof
... Pour une fonction, cela renvoie en réalité une "fonction", une sorte de In a Dans un sens, c'est très utile, mais renvoyer un objet à une valeur nulle ne peut être considéré que comme un gain ou une perte. null
function
Je pense que la façon d'approfondir notre compréhension des variables est de comprendre comment elles fonctionnent en dessous. En fait, il n'y a rien de remarquable. La valeur d'origine est placée directement dans la zone de pile mémoire, et la valeur de type référence est placée dans la
zone de tas mémoire(c'est son stockage réel). emplacement de la zone); (S'il s'agit d'une constante, elle sera placée dans le pool, qui semble faire partie de la zone de pile). Dans des circonstances normales, les valeurs des variables sont obtenues directement à partir de la zone de pile mémoire, mais les valeurs de type référence sont placées dans le tas de mémoire, alors que dois-je faire ? Vous guidez étape par étape pour comprendre les variables et lenvironnement lexical en Javascriptccès aux valeurs de type référence : 1. Une variable de type référence enregistrera un pointeur dans la
pile mémoire2. l'adresse mémoire utilisée pour référencer la zone de stockage dans le tas mémoire
3 Lors de l'accès à une valeur de type . 4、会通过指针找到内存堆中的存储区,然后从中获取值。 例如: 映射图如下: 注意:此处我用 ref. first表示 存储区的引用 , 因为虽然保存的尽管是指针,但是在访问这个值时,会进行二次解析(即通过这个指针找到存储区), 而不是直接返回这个指针的具体数据。详细可以参考 C++引用。 初识词法环境 想必各位都已经对什么是作用域了若指掌,但是我还是必须重新提一下。作用域是标识符的可访问范围,在Javascript中的任何操作,几乎都有作用域的参与。Javascript中使用词法环境决定作用域,在下面我会简单介绍一下。(请注意,这里我没有用变量这个术语,因为解析标识符范围时,应该还没有真正生成代码,感兴趣的可以去了解一下Vous guidez étape par étape pour comprendre les variables et lenvironnement lexical en JavascriptST语法树) 看,以下代码: 的确是正确输出了, 但是我更喜欢把 结果就是 因为执行过程是这样的: 现在应该提一下概念了,词法环境(Lexical Environment)就是根据代码结构时决定的作用域,也可以称作词法作用域(Lexical Scoping)它是静态作用域。可以这么说,在源代码写好时,所有标识符的作用域就已经被决定。当然也有动态作用域,你可以去试试bash脚本,它就是动态的。嘿嘿。详细也可以参考静态作用域、词法作用域。 此处只要发现了个中区别就极好掌握,所以我就略了。 词法环境的抽象 在Javascript常用三种词法环境: 一、块级作用域 二、全局作用域 三、函数作用域。 有时,我们会将一个词法环境(即作用域,下面我会正式使用词法环境替代作用域这个术语)抽象成伪代码,如下: 很简单: 例如: 一定不要忽略 然后写成抽象就是: 函数作用域: OKay,先到这里吧。 一些问题: 1、为什么用词法环境代替作用域? 2、环境记录是什么? 最后 我把我的笔记,重新整理后发到博客上后发现——我笔记干净了好多,艹。 Ce type de contenu qui n'approfondit que le noyau est très utile, et il devient également beaucoup plus flexible lors de l'écriture de code. Je pense que c'est la partie la plus utile. Cet article est reproduit à partir de : https://blog.csdn.net/krfwill/article/details/106155266 Recommandations de didacticiel associées : Vidéo JavaScript tutoriel var first = {
name:'hahei...'
}
var gggiii=111222;
var val=111;
function hahaha(){
console.log(val);
}
function hihihi(){
hahaha();
}
hihihi(); /// 111
111
。val
放在一个函数中,如: function hahaha(){
console.log(val); /// (**)
}
function hihihi(){
var val=111; /// (*)
hahaha();
}
hihihi();
Uncaught ReferenceError: val is not defined
, 根本没找到val
这个标识符,这是为什么?
hihihi
函数执行 , 然后为 val
赋值……hahaha
函数执行hahaha
找不到val
标识符,便去外部词法环境
hahaha
外部词法环境就是** hahaha函数声明时代码的外部**,即全局代码(下称全局词法环境)
(请注意3-5
步, 找val找的是函数声明代码的外部,而不是函数调用时的位置。) LexicalEnvironment = {
OuterEnv: ,
This : ,
EnvironmentRecord:{
// ... identifiername:variable
}
}
this
的值,但它是运行时决定的。 function first(){
var a =100;
let d = 220;
{ // Block,
var b = a+100;
let c = b*10;
console.log(a,b,c,d);
}
}
first(); // 100 200 2000 220
first
函数中的块级作用域,这很重要。
函数内部的块级作用域: BlockEnv = {
OuterEnv: ,
This : ,
EnvironmentRecord:{
c: // 这里没有b
}
}
FuncEnv = {
OuterEnv: ,
This : ,
EnvRec:{
a:,
d:,
b:
}
}
–词法环境涵盖了作用域,但反之则不能。
–但注意,词法作用域和词法作用域链与作用域以及作用域链都可通用。
–当前环境下的标识符-变量的映射
–但是标识符只是“合法标识符”的字符串形式。
–变量是是指存储区的内容,但是确切说法是存储区。
Enfin :
Ma compréhension personnelle est que je fais souvent des erreurs en regardant bien et je ne sais pas où aller, j'espère que vous en serez conscient.
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!