Home  >  Article  >  Web Front-end  >  Are the values ​​output by the es6 module copied?

Are the values ​​output by the es6 module copied?

青灯夜游
青灯夜游Original
2022-10-18 15:29:561032browse

No, the ES6 module outputs a reference to the value, while the CommonJS module outputs a copy of the value. In the ES6 module, when the JS engine statically analyzes the script and encounters the module loading command import, it will generate a read-only reference; when the script is actually executed, it will go to the loaded module based on this read-only reference. Take value. ES6 modules are dynamic references. ES6 modules do not cache running results, but dynamically obtain values ​​from the loaded module, and variables are always bound to the module in which they are located.

Are the values ​​output by the es6 module copied?

## The operating environment of this tutorial: Windows 7 system, ECMAScript version 6 , Dell G3 computer.


Browser loading

By default, the browser

loads JavaScript scripts synchronously, that is, when the rendering engine encounters It will stop when it reaches the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag, wait until the script is executed, and then continue to render downwards.

If it is an external script, the script download time must also be added.

If the script is large in size, it will take a long time to download and execute, thus causing the browser to be blocked. Users will feel that the browser is "stuck" and there is no response. This is obviously a very bad experience, so the browser allows asynchronous loading of scripts. The following are two syntaxes for asynchronous loading.

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

3f1c4e4b6b16bbbd69b2ee476dc4f83aIf the defer or async attribute is turned on in the tag, the script will be loaded asynchronously. When the rendering engine encounters this line of command, it will start to download the external script, but will not wait for it to be downloaded and executed, but will directly execute the following command .

  • deferIt will not be executed until the entire page is rendered normally in memory (the DOM structure is completely generated and other scripts are executed);
  • asyncOnce downloaded, the rendering engine will interrupt rendering and continue rendering after executing this script.
In a word,

defer means "execute after rendering", async means "execute after downloading" . In addition, if there are multiple defer scripts, they will be loaded in the order they appear on the page, while multiple async scripts cannot guarantee the loading order.

The browser loads the ES6 module and also uses the

3f1c4e4b6b16bbbd69b2ee476dc4f83a tag, but the type="module" attribute must be added. For 3f1c4e4b6b16bbbd69b2ee476dc4f83a with type="module", the browser will asynchronously load , will not cause the browser to be blocked, that is Wait until the entire page is rendered, and then execute the module script, which is equivalent to opening the

a907279e6cf2b736e22e16a7121cae332cacc6d41bbb37262a98f745aa00fbf0
If the web page has multiple

e91f03099790807ac093726dd6cff003, they will be processed according to the Execute in the order in which the page appears.

Note:

3f1c4e4b6b16bbbd69b2ee476dc4f83aThe async attribute of the tag can also be turned on. At this time, as long as the loading is completed, the rendering engine will interrupt the rendering and execute it immediately. After execution is complete, resume rendering. Once the async attribute is used, e91f03099790807ac093726dd6cff003 will not be executed in the order in which it appears on the page, but will be executed as long as the module is loaded.

For external module scripts (the above example is foo.js), there are a few points to note:

    The code is
  • in the module scope Run within it instead of running it in the global scope. Top-level variables inside the module are not visible externally.
  • Module script automatically
  • adopts strict mode, regardless of whether use strict is declared or not. In the
  • module, you can use the import command to load other modules (the
  • .js suffix cannot be omitted, and you need to provide an absolute URL or a relative URL), or you can use the export command to output the external interface.
  • In the module, the top-level this keyword returns
  • undefined instead of pointing to window. In other words, using this keyword at the top level of a module is meaningless.
  • If the same module is loaded multiple times, it will only be executed once.

ES6 modules are also allowed to be embedded in web pages, and the syntactic behavior is exactly the same as loading external scripts.

3acaf50c6526a47d62726f112635bc51
  import utils from "./utils.js";
  // other code
2cacc6d41bbb37262a98f745aa00fbf0

The difference between ES6 modules and CommonJS modules

CommonJS is a synchronous loading module, ES6 is an asynchronous loading module

CommonJS specification loading module is synchronous, that is to say, Only when the loading is completed, subsequent operations can be performed. Since Node.js is mainly used for server programming, module files generally already exist on the local hard disk, so they can be loaded quickly. There is no need to consider asynchronous loading, so the CommonJS specification is more 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视频教程编程视频

The above is the detailed content of Are the values ​​output by the es6 module copied?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn