Maison  >  Article  >  interface Web  >  Les valeurs sorties par le module es6 sont-elles copiées ?

Les valeurs sorties par le module es6 sont-elles copiées ?

青灯夜游
青灯夜游original
2022-10-18 15:29:561113parcourir

Non, le module ES6 génère une référence à la valeur, tandis que le module CommonJS génère une copie de la valeur. Dans le module ES6, lorsque le moteur JS analyse statiquement le script et rencontre la commande de chargement du module import, il génère une référence en lecture seule ; lorsque le script est réellement exécuté, il ira au module chargé en fonction de cette référence en lecture seule ; référence. Prendre de la valeur. Les modules ES6 sont des références dynamiques. Les modules ES6 ne mettent pas en cache les résultats en cours d'exécution, mais obtiennent dynamiquement les valeurs du module chargé, et les variables sont toujours liées au module dans lequel elles se trouvent.

Les valeurs sorties par le module es6 sont-elles copiées ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, ECMAScript version 6, ordinateur Dell G3.

Chargement du navigateur

Par défaut, le navigateur charge les scripts JavaScript de manière synchrone, c'est-à-dire que lorsque le moteur de rendu rencontre la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a, il s'arrêtera et attendra que exécution Terminez le script et continuez le rendu. 3f1c4e4b6b16bbbd69b2ee476dc4f83a标签就会停下来,等到执行完脚本,再继续向下渲染。

如果是外部脚本,还必须加入脚本下载的时间。

如果脚本体积很大,下载和执行的时间就会很长,因此造成浏览器堵塞,用户会感觉到浏览器“卡死”了,没有任何响应。这显然是很不好的体验,所以浏览器允许脚本异步加载,下面就是两种异步加载的语法。

<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>

3f1c4e4b6b16bbbd69b2ee476dc4f83a标签打开defer或async属性,脚本就会异步加载。渲染引擎遇到这一行命令,就会开始下载外部脚本,但不会等它下载和执行,而是直接执行后面的命令

  • defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;
  • async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。

一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

浏览器加载 ES6 模块,也使用3f1c4e4b6b16bbbd69b2ee476dc4f83a标签,但是要加入type="module"属性。浏览器对于带有type="module"3f1c4e4b6b16bbbd69b2ee476dc4f83a,都是异步加载不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了

a907279e6cf2b736e22e16a7121cae332cacc6d41bbb37262a98f745aa00fbf0

如果网页有多个f8666432049ee9d811f748637f7d3a4b,它们会按照在页面出现的顺序依次执行

注意:3f1c4e4b6b16bbbd69b2ee476dc4f83a标签的async属性也可以打开,这时只要加载完成,渲染引擎就会中断渲染立即执行。执行完成后,再恢复渲染。一旦使用了async属性,f8666432049ee9d811f748637f7d3a4b就不会按照在页面出现的顺序执行,而是只要该模块加载完成,就执行该模块。

对于外部的模块脚本(上例是foo.js),有几点需要注意:

  • 代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。
  • 模块脚本自动采用严格模式,不管有没有声明use strict。
  • 模块之中,可以使用import命令加载其他模块(.js后缀不可省略,需要提供绝对 URL 或相对 URL),也可以使用export命令输出对外接口。
  • 模块之中,顶层的this关键字返回undefined
  • S'il s'agit d'un script externe, il faut également ajouter le temps de téléchargement du script. Si le script est de grande taille, le téléchargement et l'exécution prendront beaucoup de temps, provoquant ainsi le blocage du navigateur, et l'utilisateur aura l'impression que le navigateur est "bloqué" sans aucune réponse. C'est évidemment une très mauvaise expérience, donc le navigateur permet le chargement asynchrone des scripts. Voici deux syntaxes pour le chargement asynchrone. La balise
3acaf50c6526a47d62726f112635bc51
  import utils from "./utils.js";
  // other code
2cacc6d41bbb37262a98f745aa00fbf0
3f1c4e4b6b16bbbd69b2ee476dc4f83a active l'attribut defer ou async et le script sera chargé de manière asynchrone. Lorsque le moteur de rendu rencontrera cette ligne de commande, il commencera à télécharger le script externe
mais il n'attendra pas qu'il soit téléchargé et exécuté, mais exécutera directement la commande suivante

.

    defer ne sera pas exécuté tant que la page entière n'est pas rendue normalement en mémoire (la structure DOM est complètement générée et d'autres scripts sont exécutés async) ; Une fois téléchargé, le moteur de rendu interrompra le rendu et poursuivra le rendu après l'exécution de ce script.

    En une phrase,

    defer signifie "exécuter après le rendu", async signifie "exécuter après le téléchargement"
    . De plus, s'il existe plusieurs scripts de report, ils seront chargés dans l'ordre dans lequel ils apparaissent sur la page, mais plusieurs scripts asynchrones ne peuvent pas garantir l'ordre de chargement.

    Le navigateur charge le module ES6 et utilise également la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a, mais l'attribut type="module" doit être ajouté. Le navigateur charge 3f1c4e4b6b16bbbd69b2ee476dc4f83a avec type="module" de manière asynchrone, ne bloquera pas le navigateur, c'est-à-dire qu'il attendra que la page entière soit rendue. Après cela, exécuter le script du module

    , ce qui équivaut à ouvrir 🎜
    // lib.js
    export let obj = {};
    // main.js
    import { obj } from './lib';
    obj.prop = 123; // OK
    obj = {}; // TypeError
    🎜Si la page Web comporte plusieurs e91f03099790807ac093726dd6cff003, ils seront exécutés dans l'ordre 🎜dans l'ordre dans lequel ils apparaissent la page🎜 . 🎜🎜🎜Remarque : L'attribut asynchrone de la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a peut également être activé à ce moment-là, tant que le chargement est terminé, le moteur de rendu interrompra le rendu et l'exécutera. immédiatement. Une fois l'exécution terminée, reprenez le rendu. Une fois l'attribut async utilisé, e91f03099790807ac093726dd6cff003🎜 ne sera pas exécuté dans l'ordre dans lequel il apparaît sur la page, mais sera exécuté tant que le module est chargé. 🎜🎜🎜🎜Pour les scripts de module externes (l'exemple ci-dessus est foo.js), il y a quelques points à noter : 🎜
      🎜Le code 🎜s'exécute dans la portée du module🎜, pas dans la portée globale. Les variables de niveau supérieur à l'intérieur du module ne sont pas visibles de l'extérieur. 🎜🎜Le script du module 🎜adopte automatiquement le mode strict🎜, que use strict soit déclaré ou non. 🎜🎜Dans le module, vous pouvez utiliser la commande import pour charger d'autres modules (le suffixe 🎜.js ne peut pas être omis, vous devez fournir une URL absolue ou une URL relative🎜), ou vous pouvez utiliser la commande export pour afficher le fichier externe. interface. 🎜🎜Dans le module, le mot-clé de niveau supérieur this renvoie undefined au lieu de pointer vers la fenêtre. En d’autres termes, utiliser ce mot-clé au niveau supérieur d’un module n’a aucun sens. 🎜🎜🎜Si le même module est chargé plusieurs fois, il ne sera exécuté qu'une seule fois🎜. 🎜🎜🎜🎜Les modules ES6 peuvent également être intégrés dans des pages Web, et le comportement syntaxique est exactement le même que celui du chargement de scripts externes. 🎜rrreee🎜🎜La différence entre les modules ES6 et les modules CommonJS🎜🎜🎜🎜CommonJS est un module de chargement synchrone, ES6 est un module de chargement asynchrone🎜🎜🎜🎜🎜Le module de chargement de spécification CommonJS est synchrone🎜, c'est-à-dire,🎜Seulement lorsque le chargement est terminé, vous pouvez effectuer les opérations suivantes🎜. Étant donné que Node.js est principalement utilisé pour la programmation du serveur, les fichiers de module existent généralement déjà sur le disque dur local, ils peuvent donc être chargés rapidement. Il n'est pas nécessaire d'envisager un chargement asynchrone, la spécification CommonJS est donc plus applicable. 🎜

    但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用异步模式

    浏览器加载 ES6 模块是异步加载不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本


    CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

    CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

    ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值

    换句话说,ES6 的import有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,ES6 模块不会缓存运行结果,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块。

    由于 ES6 输入的模块变量,只是一个“符号连接”,所以这个变量是只读的,对它进行重新赋值会报错。上面代码中,main.js从lib.js输入变量obj,可以对obj添加属性,但是重新赋值就会报错。因为变量obj指向的地址是只读的,不能重新赋值,这就好比main.js创造了一个名为obj的const变量。

// lib.js
export let obj = {};
// main.js
import { obj } from './lib';
obj.prop = 123; // OK
obj = {}; // TypeError

此外,export通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例


CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成

而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成

【相关推荐:javascript视频教程编程视频

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn