15

最近、Kyle Simpson の You Don't Know JS: ES6 で以下を読みました。

「[ES6モジュールのエクスポート]内部モジュール定義の識別子への実際のバインディング(ほとんどポインターのようなもの)。」

私の混乱は、これらのバインディングが参照とどのように異なるかです...

JS での参照は非プリミティブ型 (オブジェクトなど) にのみ適用されることを理解しています。

let object1 = {a: 1};
let object2 = object1;

object1そしてobject2今、同じオブジェクトを参照しています(両方とも参照しています)。
にプロパティを追加するとobject2、 にもプロパティが追加されますobject1

object2.b = 2;
console.log(object1.b); // 2

また、バインディングはプリミティブ型と非プリミティブ型の両方に適用できることがわかります

// foo.js
export let count = 1;
export function incrementCount() { count++; }

// bar.js
import {count, incrementCount} from foo;
console.log(count); // 1
incrementCount();
console.log(count); // 2

プリミティブ値もバインディングを共有できることを除いて、バインディングは参照と同じですか (参照は非プリミティブ型に限定されます)?

ここで何かが欠けているような気がします...

4

3 に答える 3

15

バインディングは、 「名前が参照するもの」を表す非常に一般的な用語です。スコープ内のすべての識別子は何かにバインドされています。通常、それらは変数環境 (環境レコードのストレージ スロット) の変数に解決されますが、例外があります (たとえばwith、グローバル オブジェクト)。

参照は、ある種の構造体へのポインタを表す用語です。たとえば、オブジェクトはID を使用して変更可能なプロパティのコンテナーを参照するため、 "参照値" として知られています。

ES6 モジュールは、以前は知られていなかった新しいタイプのバインディングを導入しています。これは通常の変数ではなく、文字通り別の変数 (別のモジュールからエクスポートされた変数) への参照です。モジュール変数が変更された場合、これはインポートによって反映されます - どちらも同じ環境レコード スロットを指します。宣言は、ローカル名からモジュール インターフェイスの名前へのマッピングを追加しますが、宣言は、それぞれのモジュール インターフェイスの名前からローカル名へのマッピング
を追加します。モジュールがインスタンス化されると、エクスポート モジュールのローカル バインディングと同じ環境を指す間接バインディングが作成されます。exportimport

于 2016-08-31T22:26:56.637 に答える
9

@Bergi の優れた回答にもかかわらず、背景知識が少ないユーザーには、より詳細な回答を提供したいと思います。

名前バインディング

名前バインディングは、Javascript のレキシカル スコープ規則に従って、識別子と名前付きメモリ チャンク (変数) との関連付けです。識別子はさまざまなスコープに存在し、さまざまな変数に使用できるため、名前バインディングが必要です。

function f() { let x = 0 }

let x = 1;
   
{ let x = 2 }
    
{ let x = 3;
  { let x = 4; 
    { console.log(x) } // logs 4
  }
}

名前バインディング プロセスが完了すると、 value にバインドされている周囲のスコープの をconsole.log(x)参照します。x4

名前バインディングは、特定のスコープで識別子が参照する変数を決定します。

プリミティブ型と参照型

バインディングの関連付けられた値は、次のいずれかを表すことができます

  • 値/プリミティブ型
  • または参照型

プリミティブ型は Javascript では不変です。プリミティブを関数に渡したり、別の識別子に割り当てたりすると、実際には値のコピーを操作します。プリミティブ値の ID は、その値によって与えられます。つまり、ID はありません。

参照型は Javascript で変更可能です。参照型を関数に渡したり、別の識別子に割り当てたりすると、実際にはその参照のコピー (値でもある) を操作します。したがって、参照ではなく参照を渡します。この区別は重要です。Javascript には、値による呼び出しの評価戦略しかなく、参照による呼び出しはありません。参照型には、その値から分離された ID があります。したがって、それらは名前バインディング間で共有できます。

const x = "no identity",
 y = "no identity";

const o = {foo: "identity"},
 p = {foo: "identity"};
 
// value types don't have identity
console.log(x === y); // true

// reference types have identity
console.log(o === p); // false

let q = o;

// mutations of reference types can be shared
q.bar = "mutation";
console.log(o); // {foo: "identity", bar: "mutation"}

// but rebindings can't be chared
q = {baz: "rebinding"};
console.log(q); // {baz: "rebinding"}
console.log(o); // {foo: "identity", bar: "mutation"}

参照は、アイデンティティと対応する値を共有する機能を作成します。

ES6 モジュールのバインディング

ES6 モジュールは、これまで JavaScript では知られていなかった新しいタイプの名前バインディングをエクスポートします。モジュールのエクスポートされたバインディングをインポートするAと、インポート名と参照のバインディングが作成されます。ただし、この参照はオブジェクトではなく、のエクスポート バインディングを参照しますA。モジュール間で参照型だけでなくプリミティブも共有できるようになりました。

于 2016-09-03T08:02:10.120 に答える