いずれの場合も、コードの実行中は this の値は変更されません。つまり、変数ではないため、新しい値を割り当てることはできません (対照的に、Python ではプログラミング言語。オブジェクト自体として明確に定義されており、実行時に継続的に変更できます。)
var bar = {
x: 20,
test: function () {
alert(this === bar) // true
alert(this); .x) ; // 20
this = foo; // エラー、this の値はいつでも変更できません
alert(this.x); //エラー。20 ではなく 10 である必要があります。
}
};
// コンテキスト
// これはバー オブジェクトとみなされます
// "bar" オブジェクトとして決定される; その理由 -
// 以下で詳しく説明します
bar.test(); // true、20
foo。 test = bar.test;
// ただし、これは foo ではありません
// 同じ関数が呼び出されますが、
foo.test(); // false 10
したがって、関数コード内のこの値の変更に影響を与える要因がいくつかあります。
まず、通常の関数呼び出しでは、これはコンテキスト コードをアクティブにする呼び出し元によって提供されます。つまり、関数の親コンテキストを呼び出します。これは関数の呼び出し方法によって異なります。
どのような状況でも this の値を正確に判断するには、この重要な点を理解し、覚えておく必要があります。呼び出しのコンテキストで this 値に影響を与えるのは関数の呼び出し方法であり、他には何も影響しません (一部の記事や JavaScript に関する本でさえ、「this 値は関数の定義方法に依存する」と主張されています) 、グローバル関数の場合、これはグローバル オブジェクトに設定されますが、関数がオブジェクトのメソッドの場合、これは常にオブジェクトを指します - これは絶対に当てはまりません)。トピックを続けると、通常のグローバル関数でも、さまざまな形式の呼び出しメソッドによってアクティブ化され、異なる this 値が得られることがわかります。
function foo() {
alert (これ) ;
}
foo(); // グローバル
alert(foo === foo.prototype.constructor) // true
/ / しかし、同じ 関数の呼び出し式が異なる場合、これは異なります
foo.prototype.constructor(); // foo.prototype
は定義されたメソッドとして使用できます一部のオブジェクトによって関数が呼び出されますが、これはこのオブジェクトに設定されません。
var foo = {
bar: function () {
alert(this);
alert(this === foo)
foo.bar();
var exampleFunc = foo.bar;
alert(exampleFunc === foo.bar); // true
// 同じものに対する別の呼び出し式function 、これは異なります
exampleFunc(); // global, false
では、関数の呼び出し方法は this の値にどのように影響するのでしょうか?この値の決定を完全に理解するには、その内部型の 1 つである参照型 (Reference 型) を詳細に分析する必要があります。
参照型 (参照型)
疑似コードを使用すると、参照型の値を 2 つのプロパティを持つオブジェクトとして表すことができます。base (つまり、プロパティを持つオブジェクト) と propertyName の Base です。 。
var valueOfReferenceType = {
base:
,
propertyName:
参照型の値には 2 つの状況しかありません:
識別子
またはプロパティ アクセサー
識別子の処理については、次の記事で詳しく説明します。ここで知っておく必要があるのは、このアルゴリズムの戻り値が常に参照型の値であることだけです (これは、これは言うことが重要です)。
識別子は、グローバル オブジェクト内の変数名、関数名、関数パラメータ名、および認識されないプロパティ名です。たとえば、次の識別子の値:
function bar() {}
演算の中間結果の参照型に対応する値は次のとおりです:
base: global,
propertyName : 'foo'
};
var barReference = {
base: global,
propertyName: 'bar'
};疑似コードで参照型からオブジェクトの実際の値を取得するには GetValue メソッドは次のように記述できます:
コードをコピー
varbase = GetBase(value);
if (base === null) {
throw new ReferenceError;
returnbase.[ [Get]](GetPropertyName(value));
}
内部 [[Get]] メソッドは、継承されたプロパティの分析を含む、オブジェクトのプロパティの実際の値を返します。プロトタイプチェーン。
コードをコピー
コードは次のとおりです:
GetValue(fooReference); // 10
GetValue(barReference); // 関数オブジェクト "bar"
属性アクセサーはすべておなじみのはずです。これには、ドット (.) 構文 (プロパティ名が正しい識別子で、事前にわかっている場合) と括弧構文 ([]) の 2 つのバリエーションがあります。
foo.bar(); foo[' bar']();
中間計算の戻り値には参照型の値が入っています。
var fooBarReference = {
base: foo,
propertyName: 'bar'
};
GetValue(fooBarReference); // 関数オブジェクト "bar"
参照型の値関数コンテキスト内のこの値はどのように関連しているのでしょうか? —最も重要な意味で。 この関連付けのプロセスがこの記事の中心です。 関数コンテキストで this の値を決定するための一般的な規則は次のとおりです。
関数コンテキストでは、this は呼び出し元によって提供され、関数の呼び出し方法によって決定されます。呼び出し括弧 () の左側が参照型の値である場合、これは参照型値の基本オブジェクトに設定されます。それ以外の場合 (参照型とは異なるその他のプロパティ)、この値は null になります。 。ただし、this の値が null である実際の状況はありません。this の値が null の場合、その値は暗黙的にグローバル オブジェクトに変換されるからです。注: ECMAScript の第 5 版では、グローバル変数への変換は強制されなくなり、未定義に割り当てられます。
この例のパフォーマンスを見てみましょう:
function foo() {
return this;
}
foo(); // グローバル
呼び出し括弧の左側は Reference 型の値です (foo は識別子であるため)。
var fooReference = {
base: global,
propertyName: 'foo'
};
同様に、これも参照型の基本オブジェクトに設定されます。それがグローバルオブジェクトです。
同様に、プロパティ アクセサーを使用します:
var foo = {
bar: function () {
return this;
}
} // foo
ここでも foo オブジェクトをベースとする参照型があり、これは関数 bar がアクティブ化されたときに使用されます。
コードをコピー
propertyName: 'bar'
};
ただし、同じ関数を別の形式でアクティブにすると、他の this 値が取得されます。
コードをコピーします
test は識別子として使用されるため、参照型の他の値が生成され、そのベース (グローバル オブジェクト) がこの値として使用されます。
コードをコピー
};
これで、異なる形式の式で同じ関数をアクティブ化すると、この値が異なる理由が明確にわかります。さまざまな参照型 (参照型) の中間値。
コードをコピー