ホームページ > 記事 > ウェブフロントエンド > es6モジュールが出力した値がコピーされるのでしょうか?
このチュートリアルの動作環境: Windows 7 システム、ECMAScriptバージョン 6、Dell G3 コンピューター。いいえ、ES6 モジュールは値への参照を出力しますが、CommonJS モジュールは値のコピーを出力します。 ES6 モジュールでは、JS エンジンがスクリプトを静的に分析し、モジュール読み込みコマンドのインポートに遭遇すると、読み取り専用の参照を生成します。スクリプトが実際に実行されると、この読み取り専用に基づいて、読み込まれたモジュールに移動します。参照。値を取得します。 ES6 モジュールは動的参照です。ES6 モジュールは実行結果をキャッシュしませんが、ロードされたモジュールから値を動的に取得し、変数は常にそれらが配置されているモジュールにバインドされます。
デフォルトでは、ブラウザ外部スクリプトの場合は、スクリプトのダウンロード時間も追加する必要があります。 スクリプトのサイズが大きい場合、ダウンロードと実行に時間がかかるため、ブラウザがブロックされ、ユーザーはブラウザが「スタック」して応答がないように感じます。これは明らかに非常に悪いエクスペリエンスであるため、ブラウザではスクリプトの非同期読み込みが許可されています。非同期読み込み用の 2 つの構文を次に示します。は JavaScript スクリプト を同期的に読み込みます。つまり、レンダリング エンジンが3f1c4e4b6b16bbbd69b2ee476dc4f83a
タグに到達すると停止し、スクリプトが実行されるまで待機し、下方向にレンダリングを続けます。
<script src="path/to/myModule.js" defer></script> <script src="path/to/myModule.js" async></script>
3f1c4e4b6b16bbbd69b2ee476dc4f83aタグ内で defer または async 属性がオンになっている場合、スクリプトは非同期でロードされます。レンダリング エンジンは、このコマンド行を検出すると、外部スクリプト
のダウンロードを開始しますが、ダウンロードされて実行されるのを待たずに、次のコマンド を直接実行します。
ページ全体がメモリ内で正常にレンダリングされるまで実行されません (DOM 構造が完全に生成され、他のスクリプトが実行される);
ダウンロードされると、レンダリング エンジンはレンダリングを中断し、このスクリプトの実行後にレンダリングを続行します。
つまり、3f1c4e4b6b16bbbd69b2ee476dc4f83adefer は「レンダリング後に実行」、async は「ダウンロード後に実行」という意味です。さらに、複数の遅延スクリプトがある場合、それらはページに表示される順序で読み込まれますが、複数の非同期スクリプトは読み込み順序を保証できません。
ブラウザは ES6 モジュールをロードし、
タグも使用しますが、type="module"
属性を追加する必要があります。 type="module"
を持つ 3f1c4e4b6b16bbbd69b2ee476dc4f83a
の場合、ブラウザは を非同期的に読み込みますが、
によってブラウザはブロックされません。ページ全体がレンダリングされるまで待ってから、モジュール スクリプト を実行します。これは、
a907279e6cf2b736e22e16a7121cae332cacc6d41bbb37262a98f745aa00fbf0Web ページに複数の e91f03099790807ac093726dd6cff003 がある場合、モジュール スクリプト を開くのと同じです。
の場合、ページが表示される順序で Execute
に従って処理されます。
3f1c4e4b6b16bbbd69b2ee476dc4f83aコードはタグの async 属性をオンにすることもできます。このとき、読み込みが完了している限り、レンダリング エンジンは中断されます。レンダリングを開始してすぐに実行します。実行が完了したら、レンダリングを再開します。 async 属性を使用すると、
外部モジュール スクリプト (上記の例は foo.js) の場合、注意すべき点がいくつかあります。e91f03099790807ac093726dd6cff003
はページに表示される順序では実行されず、モジュールが存在する限り実行されます。ロードされています。
3acaf50c6526a47d62726f112635bc51 import utils from "./utils.js"; // other code 2cacc6d41bbb37262a98f745aa00fbf0
ES6 モジュールと CommonJS モジュールの違い
、つまり読み込みが完了した場合のみ、後続の操作を実行できます 。 Node.js は主にサーバー プログラミングに使用されるため、通常、モジュール ファイルはローカル ハードディスク上にすでに存在しているため、すぐに読み込むことができ、非同期読み込みを考慮する必要がないため、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 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
【相关推荐:javascript视频教程、编程视频】
以上がes6モジュールが出力した値がコピーされるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。