Maison >interface Web >js tutoriel >Vous guidez étape par étape pour comprendre les variables et l'environnement lexical en Javascript

Vous guidez étape par étape pour comprendre les variables et l'environnement lexical en Javascript

青灯夜游
青灯夜游avant
2020-07-07 15:54:273492parcourir

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 à la

valeur ; 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

), nous indiquant que

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

initialiser automatiquement

les variables déclarées par

, et Javascript attribuera automatiquement une valeur non définie aux variables déclarées par

. varPar exemple :

var a = a;console.log(a);    // undefined.
Regardez, ils sont évidemment similaires, mais les résultats sont complètement différents. varMais c'est en fait inutile. Voir le code ci-dessous :

var a = a;console.log(a+2);   // NaN
Le résultat est

, ce qui est un résultat que nous ne voulons pas du tout. Lorsque
si le calcul mathématique échoue

sans problème, Javascript donnera un résultat

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 typeofTMDNaN 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 primitif

1, nombre

    2, chaîne
  • 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)
  • Je viens de présenter ces choses que vous devez savoir. Il existe d'autres documents sur un usage spécifique, je n'entrerai donc pas dans les détails. Mais une chose à ajouter à propos de
est que pour

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. nullfunctionJe 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émoire

2. 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、会通过指针找到内存堆中的存储区,然后从中获取值。

例如:

  var first  = {
      name:'hahei...'
  }
  var gggiii=111222;

映射图如下:

Vous guidez étape par étape pour comprendre les variables et lenvironnement lexical en Javascript

注意:此处我用 ref. first表示  存储区的引用 , 因为虽然保存的尽管是指针,但是在访问这个值时,会进行二次解析(即通过这个指针找到存储区), 而不是直接返回这个指针的具体数据。详细可以参考 C++引用。

初识词法环境

想必各位都已经对什么是作用域了若指掌,但是我还是必须重新提一下作用域标识符的可访问范围,在Javascript中的任何操作,几乎都有作用域的参与。Javascript中使用词法环境决定作用域,在下面我会简单介绍一下。(请注意,这里我没有用变量这个术语,因为解析标识符范围时,应该还没有真正生成代码,感兴趣的可以去了解一下Vous guidez étape par étape pour comprendre les variables et lenvironnement lexical en JavascriptST语法树

看,以下代码:

 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这个标识符,这是为什么?

因为执行过程是这样的:

  1. hihihi函数执行  , 然后为 val赋值……
  2. hahaha函数执行
  3. hahaha找不到val标识符,便去外部词法环境
  4. hahaha外部词法环境就是** hahaha函数声明时代码的外部**,即全局代码(下称全局词法环境)
  5. 全局词法环境没找到val,终了。
    (请注意3-5步, 找val找的是函数声明代码的外部,而不是函数调用时的位置。)

现在应该提一下概念了,词法环境(Lexical Environment)就是根据代码结构时决定的作用域,也可以称作词法作用域(Lexical Scoping)它是静态作用域。可以这么说,在源代码写好时,所有标识符的作用域就已经被决定。当然也有动态作用域,你可以去试试bash脚本,它就是动态的。嘿嘿。详细也可以参考静态作用域词法作用域

此处只要发现了个中区别就极好掌握,所以我就略了。

词法环境的抽象

在Javascript常用三种词法环境: 一、块级作用域 二、全局作用域 三、函数作用域。

有时,我们会将一个词法环境(即作用域,下面我会正式使用词法环境替代作用域这个术语)抽象成伪代码,如下:

	LexicalEnvironment = {
		OuterEnv:  ,
		This :    ,
		EnvironmentRecord:{
			// ... identifiername:variable
		}
	}

很简单:

  • OuterEnv:当前词法环境的外部词法环境
  • This: 当前词法环境的 this的值,但它是运行时决定的。
  • EnvironmentRecord(环境记录): 标识符-变量的映射,注意,这里的标识符只是单纯的字符串,变量指的是存储区的数据。而且标识符必须是当前词法环境,而不是当前代码的。

例如:

  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:
		}
	}

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.
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.

Cet article est reproduit à partir de : https://blog.csdn.net/krfwill/article/details/106155266

Recommandations de didacticiel associées : Vidéo JavaScript tutoriel

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer