導入
1. 参照タイプ
参照型は JavaScript の内部型です。これは主に変数や関数を置き換える参照として使用されます。もちろん、実際の値が必要な場合は、それを通じて実際の値を見つけることができます。
2. 参照型の構造
参照型の値は 2 つの部分で構成されます。1 つは、参照型の値によって参照されるオブジェクトが属するオブジェクトであり、もう 1 つは、base で参照されるオブジェクトのオブジェクト名です。 。疑似コードで表すと次のようになります。
次のようにコードをコピーします。
var valueOfReferenceType = {
ベース: <ベース オブジェクト>,
propertyName: <プロパティ名>
};
3.利用シーン
参照型には 2 つの使用シナリオがあります。
(1) 識別子を加工する場合
識別子は、グローバル オブジェクト内の変数名、関数名、関数パラメータ名、および認識されないプロパティ名です。
(2) プロパティアクセサを処理する場合
次のようにコードをコピーします。
var foo = 10;
関数バー( ){}
操作の中間結果では、参照型は以下に対応します。
次のようにコードをコピーします。
var fooReference = {
ベース: グローバル、
プロパティ名: 'foo'
};
var barReference = {
ベース: グローバル、
プロパティ名: 'バー'
};
ここで基本を説明する必要がありますが、JavaScript では、すべてのオブジェクトまたは関数が独自のオブジェクトを持っています。私の以前の記事を読んだ人なら誰でも、この実行コンテキスト内の変数または関数を管理するための変数オブジェクトがあることを知っています。 。
したがって、識別子を扱う場合は次のようになります。
グローバルな文脈では、言うまでもなく、base === globalVO === global
関数の実行コンテキストでは、base === VO/AO
ただし、処理オブジェクトのプロパティは次のとおりです。
これはさらに単純です。base === owerObject
4. 参照型の真の値を取得する
冒頭で述べたように、参照型は単なる参照であり、実際の値を格納するわけではありません。実際の値が必要な場合は、一連の内部アルゴリズムを通じて取得できます。このアルゴリズムは単純な擬似コードで記述できます。
次のようにコードをコピーします。
関数 GetValue(値) {
if (タイプ(値) != 参照) {
戻り値;
}
var ベース = GetBase(値);
if (base === null) {
新しい ReferenceError をスローします。
}
returnbase.[[Get]](GetPropertyName(value));
}
内部 [[Get]] メソッドは、プロトタイプ チェーンで継承されたプロパティの分析を含む、オブジェクトのプロパティの真の値を返します。したがって、GetValue を使用すると、参照型の実際の値を簡単に取得することもできます。例えば:
次のようにコードをコピーします。
GetValue(fooReference); // 10
GetValue(barReference); // 関数オブジェクト「バー」
では、いつ参照型の実際の値を取得する必要があるのでしょうか?
一般に、参照型を割り当てる必要がある場合、操作に参加する必要がある場合、または参照型を呼び出す必要がある場合は、GetValue メソッドを通じて実際の値を取得する必要があります。 (注: GetValue によって取得されたオブジェクトは参照型ではなくなりました)
参照型とこれの関係
参照型は主に関数コンテキストの this 点と密接に関連しており、異なる時点でまったく異なるように見えるため、関数コンテキストでの this のパフォーマンスを具体的に説明するために参照型を紹介します。
関数コンテキストで this の値を決定するための一般的な規則は次のとおりです。
関数のコンテキストでは、これは呼び出し元によって提供され、関数の呼び出し方法によって決まります。呼び出し括弧 () の左側が参照型の値である場合、これは参照型値の基本オブジェクトに設定されます。それ以外の場合 (参照型とは異なるその他のプロパティ)、この値は null になります。 。ただし、this の値が null である実際の状況はありません。this の値が null の場合、その値は暗黙的にグローバル オブジェクトに変換されるからです。注: ECMAScript の第 5 版では、グローバル変数への変換は強制されなくなり、未定義に割り当てられます。
以下では、呼び出し括弧の左側の違いに基づいて 3 つの状況について説明します。
(1) 呼び出し括弧の左側は参照型の値です
これにはあまり多くの分析は必要ありません。ベース オブジェクトはこの値を見つけるだけです。グローバル変数の下で宣言されている場合は、グローバル オブジェクトを指します。
次のようにコードをコピーします。
var myObject = {
foo : function(){
コンソール.ログ(これ);
}
}
myObject.foo(); // foo のベースが myObject であることは間違いないため、foo メソッドの this は myObject を指します。
(2) 呼び出し括弧の左側は参照型の値ですが、この値は null です
次のようにコードをコピーします。
関数 myFunction() {
var foo = function(){
コンソール.ログ(これ);
}
foo(); //AO.foo() => null.foo()
}
myFunction(); //出力: ウィンドウ {トップ: ウィンドウ, ウィンドウ: ウィンドウ...}
内部関数が呼び出されるとき、内部関数のベースは現在の実行コンテキストのアクティブ オブジェクト (OA) である必要があります。ただし、JavaScript 内で OA がベースとして使用される場合、JavaScript は必ず null として扱われます。これを null にすると、すべてのベースがグローバル オブジェクトに設定されます (これが、前のこの関数呼び出しパターンの設計エラーの原因です)。したがって、この場合、これはグローバル オブジェクトを指します。
(3) 参照型ではない括弧の左側の値を呼び出す
次のようにコードをコピーします。
//簡単な例
(関数 () {
console.log(this); // null => グローバル
})();
//より複雑な例
var foo = {
バー: 関数 () {
コンソール.ログ(これ);
}
};
foo.bar(); // 参照、OK => foo
(foo.bar)(); // 参照、OK => foo
(foo.bar = foo.bar)(); // グローバル
(false || foo.bar)(); // グローバル
(foo.bar, foo.bar)(); // グローバル
呼び出し括弧の左側が参照型ではなく別の型である場合、これは自動的に null に設定され、結果はグローバル オブジェクトになります。
最初の例では、即時関数の関数呼び出しのかっこの左側に参照ではなく式があります。
2 番目の例はさらに複雑なので、1 つずつ分析してみましょう。
foo.bar()、これについては疑いの余地はありません。base は foo であり、this は foo を指します。
(foo.bar)() では、ここでは括弧が使用されています。これはグループ化記号として機能します。つまり、参照型に GetValue メソッドの実行を強制するものではなく、実行結果は上記とまったく同じになります。
括弧内の次の 3 つは代入演算、または演算とコンマ演算であり、これらはすべて参照型に GetValue メソッドを強制的に実行させ、それによって関数オブジェクトを返します。このように、関数呼び出しのかっこの左側は参照型ではなくなるため、これはグローバル オブジェクトを指します。
要約する
参照型については、実際のところ、Uncle Tom のブログの章を見たばかりで、関数呼び出しモードでの値の原則を説明するために、この分析を行いました。信じられないことに、私は参照型と値による参照の間に何らかの関係があるべきだと常に考えていましたが、予想外なことに、これはこれを理解するためにのみ使用されます。両者に以前から関係があったのか、関係があったとしたらどのような関係だったのかについては、今後も引き続き調査・研究する必要がある。
もっとコミュニケーションが取れるといいですね。アンクル・トムに感謝したいと思います。