ホームページ >ウェブフロントエンド >フロントエンドQ&A >es6 インポートは変数をプロモートしますか?

es6 インポートは変数をプロモートしますか?

青灯夜游
青灯夜游オリジナル
2023-01-18 19:44:411403ブラウズ

ES6 インポートにより変数が昇格されます。変数ホイスティングとは、変数宣言をそのスコープの先頭に昇格させることです。 js はコンパイル フェーズと実行フェーズを経る必要があります。コンパイル フェーズでは、すべての変数宣言が収集され、変数は事前に宣言されますが、他のステートメントの順序は変更されません。したがって、コンパイル フェーズでは、最初のステップはすでに実行されています。 2 番目の部分は、ステートメントが実行フェーズで実行された場合にのみ実行されます。

es6 インポートは変数をプロモートしますか?

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

変数プロモーション

JavaScript はシングルスレッド言語であるため、実行は順番に実行する必要があります。ただし、1 行ずつ分析して実行するのではなく、部分ごとに分析して実行し、最初にコンパイル フェーズが実行され、次に実行フェーズが実行されます。コンパイル段階中、コードが実際に実行される数ミリ秒前に、すべての変数と関数の宣言が検出され、Lexical Environment と呼ばれる JavaScript データ構造内のメモリに追加されます。したがって、これらの変数と関数は、実際に宣言される前に使用できます。

簡単な例から始めましょう:

 a = 2;
 var a;
 console.log(a);

上記のコードは何を出力しますか? このコードが上から下に実行されると、間違いなく未定義の出力が出力されますが、JavaScript は次のような言語ではありません。トップダウンで実行されます。 このコードの出力は 2 ですが、これは予想外でしょうか?では、なぜこのようなことが起こっているのでしょうか? 重要な点は、変数プロモーションにあります。現在のスコープ内のすべての変数の宣言をプログラムの先頭に上げます。したがって、上記のコードは次のコードと同等です。これでより明確になりますか?

 var a;
 a = 2;
 console.log(a);

次に、別の例を見てみましょう:

 console.log(a);
 var a = 2;

このコードは何を出力しますか?出力2? 実際、このコードは unknown を出力します。これが理由です?先ほども言いましたが、JavaScript では変数の宣言は先頭に昇格しますが、代入文は昇格しません。js の場合、var a = 2 は 2 段階の解析:

var a;
a = 2;
に分割されます。

そして、js は文 var a のみをプロモートするので、今のステートメントは次と同等です:

 var a;
 console.log(a);
 a = 2;

それでは、なぜ変数のプロモートがあるのでしょうか?

変数昇格という現象はなぜ起こるのでしょうか? なぜなら、js は他の言語と同様、コンパイルと実行の段階を経る必要があるからです。 js がコンパイル段階にあるとき、すべての変数宣言を収集して事前に変数を宣言し、他のステートメントの順序は変更されないため、コンパイル段階では最初のステップが実行され、2 番目の部分が実行されます。ステートメントが実行フェーズで実行される場合のみ。

ES6 インポート変数プロモーション

ES6 インポートにより、変数プロモーションが発生します。

たとえば、次のテスト コードでは、

// a.js
console.log('I am a.js...')
import { foo } from './b.js';
console.log(foo);
// b.js
console.log('I am b.js...')
export let foo = 1;

が a.js を実行します。

// node -r esm a.js 
I am b.js...
I am a.js...
1

出力される結果は、「I am b.js..」です。 .' が最初に表示され、次に 'I am a.js...' が再び表示されます。これが変数プロモーションの現象です。

これは、ES6 が言語標準レベルでモジュール関数を実装しているためです。そのため、a.js がプリコンパイルされ、キーワード import が見つかると、最初に b.js が読み込まれるため、「私は b.js です」となります。 ...』。

全体のプロセスは次のとおりです。

es6 インポートは変数をプロモートしますか?

変数プロモーションの生成は、実際には変数オブジェクトの作成プロセスに関連しています。

変数オブジェクトの作成手順

変数オブジェクト(Variable Object)の作成は、以下の手順で順番に行われます。

es6 インポートは変数をプロモートしますか?

  • 現在のコンテキストの関数宣言、つまり function キーワードを使用して宣言された関数を確認してください。変数オブジェクトに関数名を含む属性を作成します。属性値は、関数が配置されているメモリ アドレスへの参照です。関数名属性がすでに存在する場合、その属性は新しい参照によって上書きされます。

  • 現在のコンテキストで変数宣言を確認してください。変数宣言が見つかった場合は、変数オブジェクト内に変数名を持つ属性が作成されますが、属性値は未定義です。変数名の属性が既に存在する場合、同名の関数が未定義に変更されるのを防ぐため、そのままスキップされ、元の属性値は変更されません。

function ステートメントは、var ステートメントよりも高い優先順位を持ちます。

function test() {
  console.log(a);
  console.log(foo());

  var a = 1;
  function foo() {
    return 2;
  }
}

test();

test() の実行コンテキストから直接理解を開始します。

// 创建过程
testEC = {
    // 变量对象
    VO: {},
    // 作用域链
    scopeChain: {}
}

// VO 为 Variable Object 的缩写,即变量对象
VO = {
    arguments: {...},
    foo: <foo reference>    // 表示foo的地址引用
    a: undefined
}

test() の実行結果は、

// node -r esm demo01.js 
undefined
2

実際には、上記のコードdemo01.jsは、この実行シーケンスになります、

function test() {
    function foo() {
        return 2;
    }
    var a;
    console.log(a);
    console.log(foo());
    a = 1;
}
test();

[関連する推奨事項: JavaScript 学習チュートリアル #]

以上がes6 インポートは変数をプロモートしますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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