はじめに
この記事では、実行コンテキストに直接関連する詳細について説明します。話題になっているのはこのキーワードです。このトピックは難しいことが実際に証明されており、さまざまな実行コンテキストでこれを決定する際に問題が発生することがよくあります。
多くのプログラマは、プログラミング言語において this キーワードはオブジェクト指向プログラム開発と密接に関連しており、コンストラクターによって新しく作成されたオブジェクトを完全に指すものであると信じ込んでいます。これは ECMAScript 仕様にも実装されていますが、後で説明するように、ECMAScript では、これは新しく作成されたオブジェクトを指すことだけに限定されません。
英語翻訳: Dmitry A. Soshnikov、Stoyan Stefanov の協力
発行日: 2010-03-07
http://dmitrysoshnikov.com/ecmascript/chapter-3-this/
ロシア語原文: Dmitry A. Soshnikov
訂正: Zerogif
公開: 2009-06-28;
更新: 2010-03-07
http://dmitrysoshnikov.com/ecmascript /ru-chapter-3-this/
この記事の内容の大部分は、http://www.denisdeng.com/?p=900 を参照しています。
一部の文は、justin の中国語翻訳を参照しています。
コードをコピー
これが ECMAScript で正確に何であるかを詳しく見てみましょう。
定義
これは実行コンテキストの属性です:
activeExecutionContext = {
VO: {...},
this: thisValue
};
ここでの VO は前の章の変数オブジェクトで説明しました。
これはコンテキスト内の実行可能コードのタイプに直接関係しており、この値はコンテキストに入るときに決定され、コンテキストの実行中は変更されません。
これらのケースをさらに詳しく調べてみましょう:
これはグローバル コードです
ここではすべてが簡単です。グローバル コードでは、これは常にグローバル オブジェクト自体であるため、間接的に参照することができます。
// グローバルを定義する属性を表示しますobject
this .a = 10; // global.a = 10
alert(a); // 10
// 識別されない
b = 20; 🎜> alter(this.b); // 20
// グローバル コンテキストの変数オブジェクトはグローバル オブジェクト自体であるため、
// も暗黙的に宣言されます。 = 30;
alert(this.c); // 30
関数コードで this を使用する場合は興味深いですが、この状況は困難であり、たくさんの問題。
このタイプのコードにおけるこの値の最初の (おそらく最も重要な) 特徴は、値が関数に静的にバインドされていないことです。
上で述べたように、これは関数コードに入るときに決定され、この値は毎回まったく異なります。
いずれの場合も、コードの実行中は this の値は変更されません。つまり、変数ではないため、新しい値を割り当てることはできません (対照的に、Python ではプログラミング言語。オブジェクト自体として明確に定義されており、実行時に継続的に変更できます。)
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 です。 。
propertyName:
参照型の値には 2 つの状況しかありません:
またはプロパティ アクセサー
識別子の処理については、次の記事で詳しく説明します。ここで知っておく必要があるのは、このアルゴリズムの戻り値が常に参照型の値であることだけです (これは、これは言うことが重要です)。
識別子は、グローバル オブジェクト内の変数名、関数名、関数パラメータ名、および認識されないプロパティ名です。たとえば、次の識別子の値:
演算の中間結果の参照型に対応する値は次のとおりです:
};
var barReference = {
base: global,
propertyName: 'bar'
};疑似コードで参照型からオブジェクトの実際の値を取得するには GetValue メソッドは次のように記述できます:
if (base === null) {
throw new ReferenceError;
returnbase.[ [Get]](GetPropertyName(value));
}
内部 [[Get]] メソッドは、継承されたプロパティの分析を含む、オブジェクトのプロパティの実際の値を返します。プロトタイプチェーン。
コードをコピー
コードは次のとおりです:
GetValue(fooReference); // 10
GetValue(barReference); // 関数オブジェクト "bar"
属性アクセサーはすべておなじみのはずです。これには、ドット (.) 構文 (プロパティ名が正しい識別子で、事前にわかっている場合) と括弧構文 ([]) の 2 つのバリエーションがあります。
foo.bar(); foo[' bar']();
base: foo,
propertyName: 'bar'
};
GetValue(fooBarReference); // 関数オブジェクト "bar"
関数コンテキストでは、this は呼び出し元によって提供され、関数の呼び出し方法によって決定されます。呼び出し括弧 () の左側が参照型の値である場合、これは参照型値の基本オブジェクトに設定されます。それ以外の場合 (参照型とは異なるその他のプロパティ)、この値は null になります。 。ただし、this の値が null である実際の状況はありません。this の値が null の場合、その値は暗黙的にグローバル オブジェクトに変換されるからです。注: ECMAScript の第 5 版では、グローバル変数への変換は強制されなくなり、未定義に割り当てられます。
この例のパフォーマンスを見てみましょう:
return this;
}
foo(); // グローバル
base: global,
propertyName: 'foo'
};
同様に、プロパティ アクセサーを使用します:
bar: function () {
return this;
}
} // foo
ここでも foo オブジェクトをベースとする参照型があり、これは関数 bar がアクティブ化されたときに使用されます。
コードをコピー
ただし、同じ関数を別の形式でアクティブにすると、他の this 値が取得されます。
コードをコピーします
コードをコピー
これで、異なる形式の式で同じ関数をアクティブ化すると、この値が異なる理由が明確にわかります。さまざまな参照型 (参照型) の中間値。
コードをコピー
function foo() {
alert(this);
foo(); // グローバルなので、
var fooReference = {
base: global,
propertyName: 'foo'
};
alert(foo === foo.prototype.constructor) // true
//式を呼び出す形式
foo.prototype.constructor(); // foo.prototype、なぜなら
var fooPrototypeConstructorReference = {
base: foo.prototype,
propertyName : 'constructor'
};
alert(this.bar)
}
var x = {バー: 10};
var y = {bar: 20};
x.test = foo; // 10
y.test(); // 20
関数呼び出しと非参照型
したがって、前述したように、呼び出し括弧の左側がが参照型ではなく他の型である場合、この値は自動的に null に設定され、結果はグローバル オブジェクトになります。
コードをコピーします
この例では、関数オブジェクト ただし、参照型のオブジェクトではありません (識別子やプロパティ アクセサーではありません)。したがって、 this の値は最終的にグローバル オブジェクトに設定されます。
より複雑な例:
コードをコピーします
(foo.bar)() // 参照、OK => foo
(foo.bar = foo.bar)(); || foo.bar)(); // グローバル?
にプロパティ アクセサがあるのはなぜですか?その途中 値は参照型の値である必要があります。一部の呼び出しでは、取得する this 値はベース オブジェクトではなく、グローバル オブジェクトですか?
問題は、次の 3 つの呼び出しでは、特定の操作を適用した後、呼び出し括弧の左側の値が参照型ではなくなることです。
最初の例は明白です - 明らかな参照型です。その結果、これが基本オブジェクト、つまり foo になります。
2 番目の例では、グループ演算子は適用されません。GetValue など、参照型からオブジェクトの実際の値を取得する上記のメソッドを考えてください。同様に、グループ操作の戻りでも参照型を取得します。これが、 this 値がベース オブジェクト (foo) に再度設定される理由です。
3 番目の例では、グループ演算子とは異なり、代入演算子は GetValue メソッドを呼び出します。返される結果は関数オブジェクト (参照型ではありません) です。つまり、これは null に設定され、結果はグローバル オブジェクトになります。
4 番目と 5 番目も同様です。コンマ演算子と論理演算子 (OR) が GetValue メソッドを呼び出し、それに応じて参照が失われ、関数が取得されます。そして、再度グローバルに設定します。
次のような状況があります。呼び出し側の式が呼び出し括弧の左側で参照型の値を制限している場合、これが null に設定されているにもかかわらず、結果は変換されますグローバルへ。この状況は、参照型値の基本オブジェクトがアクティブ オブジェクトである場合に発生します。
次の例では、内部関数が親関数によって呼び出されます。このとき、上記の特殊な状況がわかります。第 12 章で学んだように、ローカル変数、内部関数、および仮パラメータは、特定の関数のアクティベーション オブジェクトに格納されます。
コードをコピー
コードは次のとおりです。
アクティブなオブジェクトは常に this として返され、値は null です (つまり、疑似コードの AO.bar() は null.bar() と同等です)。ここで、これをグローバル オブジェクトに設定して、上で説明した例に戻ります。
例外が 1 つあります。with オブジェクトに関数名属性が含まれている場合、その関数は with ステートメントの内部ブロックで呼び出されます。 With ステートメントは、オブジェクトのスコープの前、つまりアクティブなオブジェクトの前に追加されます。同様に、(識別子またはプロパティ アクセサーを介した) 参照型があり、その基本オブジェクトはアクティブ オブジェクトではなく、with ステートメントのオブジェクトになります。ちなみに、with オブジェクトはスコープ チェーンの最前面のオブジェクト (グローバル オブジェクトまたはアクティブ オブジェクト) よりも前にあるため、これは内部関数だけでなくグローバル関数にも関連します。
var x = 10; 🎜>with ({
foo: function () {
alert(this.x);
},
x: 20
}) {
foo(); // 20
}
// なぜなら
var fooReference = {
base: __withObject,
propertyName: 'foo '
};
catch ステートメントの関数呼び出しの実際のパラメーターでも同じ状況が発生します。この場合、catch オブジェクトはスコープの前、つまり、アクティブなオブジェクトまたはグローバル オブジェクトのフロント。ただし、この特定の動作は ECMA-262-3 のバグであることが確認されており、ECMA-262-5 の新しいバージョンで修正されています。このようにして、特定のアクティブ オブジェクトで、this はグローバル オブジェクトを指します。 catch オブジェクトではなく。
alert(this);
} catch (e) {
e(); // ES3 標準は __catchObject、ES5 標準はグローバル
}
// アイデアについて
var eReference = {
base: __catchObject,
propertyName: 'e'
}; これは新しいバージョンで修正されました。 ES5 標準 このバグ、
// つまり、これはグローバル オブジェクトです。
var eReference = {
base: global,
propertyName: 'e'
}; 🎜> 名前付き関数の再帰呼び出しでも同じ状況が発生します (関数の詳細については、第 15 章関数を参照してください)。関数の最初の呼び出しでは、ベース オブジェクトは親アクティビティ オブジェクト (またはグローバル オブジェクト) です。再帰呼び出しでは、ベース オブジェクトは関数式のオプションの名前を格納する特定のオブジェクトである必要があります。ただし、この場合、これは常にグローバル オブジェクトを指します。
コードをコピー
コードは次のとおりです。
これは、コンストラクターとして呼び出される関数内です。
この値に関連する別の状況は、関数のコンテキスト、つまりコンストラクターの呼び出しです。
コードをコピー
コードは次のとおりです。
関数呼び出しで this を手動で設定する
関数プロトタイプで定義された 2 つのメソッド (すべての関数がそれにアクセスできるように) を使用すると、関数呼び出しで this 値を手動で設定できます。 .apply メソッドと .call メソッドです。これらは this 値として受け入れる最初の引数を使用し、これは呼び出しスコープで使用されます。これら 2 つのメソッドの違いは非常にわずかです。.apply の場合、2 番目のパラメータは配列 (または引数などの配列のようなオブジェクト) である必要があります。同様に、.call は任意のパラメータを受け入れることができます。両方のメソッドに必要なパラメータは次のとおりです。最初の ——これ。
例:
コードをコピーします
コードは次のとおりです:
var b = 10;

同事因为this指向的问题卡住的bug,vue2的this指向问题,使用了箭头函数,导致拿不到对应的props。当我给他介绍的时候他竟然不知道,随后也刻意的看了一下前端交流群,至今最起码还有70%以上的前端程序员搞不明白,今天给大家分享一下this指向,如果啥都没学会,请给我一个大嘴巴子。

本篇文章带大家解读vue源码,来介绍一下Vue2中为什么可以使用 this 访问各种选项中的属性,希望对大家有所帮助!

一、this关键字1.this的类型:哪个对象调用就是哪个对象的引用类型二、用法总结1.this.data;//访问属性2.this.func();//访问方法3.this();//调用本类中其他构造方法三、解释用法1.this.data这种是在成员方法中使用让我们来看看不加this会出现什么样的状况classMyDate{publicintyear;publicintmonth;publicintday;publicvoidsetDate(intyear,intmonth,intday){ye

什么是this?下面本篇文章给大家介绍一下JavaScript中的this,并聊聊this在函数不同调用方式下的区别,希望对大家有所帮助!

jQuery中this关键字的灵活运用在jQuery中,this关键字是一个非常重要且灵活的概念,它用来引用当前正在操作的DOM元素。通过合理的运用this关键字,我们可以方便地操作页面中的元素,实现各种交互效果和功能。本文将结合具体的代码示例,介绍this关键字在jQuery中的灵活运用。简单的this示例首先,我们来看一个简单的this示例。假设我们有一

JavaScript如何改变this指向?下面本篇文章给大家介绍一下JS改变this指向的三种方法,希望对大家有所帮助!

JavaScript中箭头函数是一种比较新的语法,没有自己的this关键字,相反箭头函数的this指向包含它的作用域对象,影响方面有:1、箭头函数中的this是静态的;2、箭头函数不能作为构造函数使用;3、箭头函数不能用作方法。

1.this引用1.1为什么要有this引用先来写一个日期类的例子:publicclassclassCode{publicintyear;publicintmonth;publicintday;publicvoidsetDay(inty,intm,intd){year=y;month=m;day=d;}publicvoidprintDate(){System.out.println(year+"-"+month+"-"+day);}publicstatic


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック



