ホームページ  >  記事  >  ウェブフロントエンド  >  es6モジュールが出力した値がコピーされるのでしょうか?

es6モジュールが出力した値がコピーされるのでしょうか?

青灯夜游
青灯夜游オリジナル
2022-10-18 15:29:561124ブラウズ

いいえ、ES6 モジュールは値への参照を出力しますが、CommonJS モジュールは値のコピーを出力します。 ES6 モジュールでは、JS エンジンがスクリプトを静的に分析し、モジュール読み込みコマンドのインポートに遭遇すると、読み取り専用の参照を生成します。スクリプトが実際に実行されると、この読み取り専用に基づいて、読み込まれたモジュールに移動します。参照。値を取得します。 ES6 モジュールは動的参照です。ES6 モジュールは実行結果をキャッシュしませんが、ロードされたモジュールから値を動的に取得し、変数は常にそれらが配置されているモジュールにバインドされます。

es6モジュールが出力した値がコピーされるのでしょうか?

このチュートリアルの動作環境: Windows 7 システム、ECMAScriptバージョン 6、Dell G3 コンピューター。


ブラウザの読み込み

デフォルトでは、ブラウザ

は JavaScript スクリプト を同期的に読み込みます。つまり、レンダリング エンジンが3f1c4e4b6b16bbbd69b2ee476dc4f83a タグに到達すると停止し、スクリプトが実行されるまで待機し、下方向にレンダリングを続けます。

外部スクリプトの場合は、スクリプトのダウンロード時間も追加する必要があります。

スクリプトのサイズが大きい場合、ダウンロードと実行に時間がかかるため、ブラウザがブロックされ、ユーザーはブラウザが「スタック」して応答がないように感じます。これは明らかに非常に悪いエクスペリエンスであるため、ブラウザではスクリプトの非同期読み込みが許可されています。非同期読み込み用の 2 つの構文を次に示します。

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

3f1c4e4b6b16bbbd69b2ee476dc4f83aタグ内で defer または async 属性がオンになっている場合、スクリプトは非同期でロードされます。レンダリング エンジンは、このコマンド行を検出すると、外部スクリプト のダウンロードを開始しますが、ダウンロードされて実行されるのを待たずに、次のコマンド を直接実行します。

  • deferページ全体がメモリ内で正常にレンダリングされるまで実行されません (DOM 構造が完全に生成され、他のスクリプトが実行される);
  • asyncダウンロードされると、レンダリング エンジンはレンダリングを中断し、このスクリプトの実行後にレンダリングを続行します。
つまり、

defer は「レンダリング後に実行」、async は「ダウンロード後に実行」という意味です。さらに、複数の遅延スクリプトがある場合、それらはページに表示される順序で読み込まれますが、複数の非同期スクリプトは読み込み順序を保証できません。

ブラウザは ES6 モジュールをロードし、
3f1c4e4b6b16bbbd69b2ee476dc4f83a

タグも使用しますが、type="module" 属性を追加する必要があります。 type="module" を持つ 3f1c4e4b6b16bbbd69b2ee476dc4f83a の場合、ブラウザは を非同期的に読み込みますが、 によってブラウザはブロックされません。ページ全体がレンダリングされるまで待ってから、モジュール スクリプト を実行します。これは、

a907279e6cf2b736e22e16a7121cae332cacc6d41bbb37262a98f745aa00fbf0
Web ページに複数の e91f03099790807ac093726dd6cff003 がある場合、モジュール スクリプト を開くのと同じです。

の場合、ページが表示される順序で Execute に従って処理されます。

注:
3f1c4e4b6b16bbbd69b2ee476dc4f83a

タグの async 属性をオンにすることもできます。このとき、読み込みが完了している限り、レンダリング エンジンは中断されます。レンダリングを開始してすぐに実行します。実行が完了したら、レンダリングを再開します。 async 属性を使用すると、e91f03099790807ac093726dd6cff003 はページに表示される順序では実行されず、モジュールが存在する限り実行されます。ロードされています。

外部モジュール スクリプト (上記の例は foo.js) の場合、注意すべき点がいくつかあります。

コードは
    です。モジュール スコープ グローバル スコープで実行するのではなく、モジュール スコープ内で
  • を実行します。モジュール内のトップレベル変数は外部からは見えません。 モジュール スクリプトは、use strict が宣言されているかどうかに関係なく、
  • strict モードを自動的に採用します
  • モジュールでは、import コマンドを使用して他のモジュールをロードできます (
  • .js サフィックスは省略できず、絶対 URL または相対 URL
  • を指定する必要があります)、または外部インターフェイスを出力するには、export コマンドを使用できます。 モジュールでは、トップレベルの this キーワードは、ウィンドウを指す代わりに
  • unknown
  • を返します。つまり、モジュールの最上位でこのキーワードを使用しても意味がありません。
  • 同じモジュールが複数回ロードされた場合、実行されるのは 1 回だけです。
  • ES6 モジュールは Web ページに埋め込むこともでき、構文上の動作は外部スクリプトを読み込む場合とまったく同じです。
3acaf50c6526a47d62726f112635bc51
  import utils from "./utils.js";
  // other code
2cacc6d41bbb37262a98f745aa00fbf0

ES6 モジュールと CommonJS モジュールの違い

CommonJS は同期読み込みモジュール、ES6 は非同期読み込みモジュール

CommonJS 仕様の読み込みモジュールは同期です
、つまり

読み込みが完了した場合のみ、後続の操作を実行できます 。 Node.js は主にサーバー プログラミングに使用されるため、通常、モジュール ファイルはローカル ハードディスク上にすでに存在しているため、すぐに読み込むことができ、非同期読み込みを考慮する必要がないため、CommonJS 仕様の適用性が高くなります。

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

浏览器加载 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视频教程编程视频

以上がes6モジュールが出力した値がコピーされるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。