ホームページ > ウェブフロントエンド > jsチュートリアル > js イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)

js イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)

php是最好的语言
リリース: 2020-09-05 09:07:18
オリジナル
18347 人が閲覧しました

この記事では、js での this の使用法を分析する例を使用します。次の例からわかるように、obj.foo() の場合、foo は obj 環境で実行されます。したがって、これは obj を指します。foo() の場合、foo はグローバル環境で実行されるため、これはグローバル環境を指します。したがって、両者の経営成績は異なります。これが決定的な役割を果たしていることがわかります。この記事が皆さんの参考値になれば幸いです。

js イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)

1. 問題の根源

JavaScript 言語を学習するには、異なる結果をもたらす可能性がある次の 2 つの記述方法を理解することが 1 つの兆候です。

var obj = {
  foo: function () {}
};

var foo = obj.foo;

// 写法一
obj.foo()

// 写法二
foo()
ログイン後にコピー

上記のコードでは、obj.foofoo は同じ関数を指していますが、実行結果は異なる場合があります。以下の例を参照してください。 obj.foofoo指向同一个函数,但是执行结果可能不一样。请看下面的例子。

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2
ログイン後にコピー

这种差异的原因,就在于函数体内部使用了this关键字。很多教科书会告诉你,this指的是函数运行时所在的环境。对于obj.foo()来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。所以,两者的运行结果不一样。

这种解释没错,但是教科书往往不告诉你,为什么会这样?也就是说,函数的运行环境到底是怎么决定的?举例来说,为什么obj.foo()就是在obj环境执行,而一旦var foo = obj.foofoo()就变成在全局环境执行?

本文就来解释 JavaScript 这样处理的原理。理解了这一点,你就会彻底理解this的作用。

二、内存的数据结构

JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系。

var obj = { foo:  5 };
ログイン後にコピー

上面的代码将一个对象赋值给变量obj。JavaScript 引擎会先在内存里面,生成一个对象{ foo: 5 },然后把这个对象的内存地址赋值给变量obj

js イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)

也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的foo属性。

原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo属性,实际上是以下面的形式保存的。

{
  foo: {
    [[value]]: 5
    [[writable]]: true
    [[enumerable]]: true
    [[configurable]]: true
  }
}
ログイン後にコピー

注意,foo属性的值保存在属性描述对象的value属性里面。

三、函数

这样的结构是很清晰的,问题在于属性的值可能是一个函数。

var obj = { foo: function () {} };
ログイン後にコピー

这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性。

{
  foo: {
    [[value]]: 函数的地址
    ...
  }
}
ログイン後にコピー

由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。

var f = function () {};
var obj = { f: f };

// 单独执行
f()

// obj 环境执行
obj.f()
ログイン後にコピー

四、环境变量

JavaScript 允许在函数体内部,引用当前环境的其他变量。

var f = function () {
  console.log(x);
};
ログイン後にコピー

上面代码中,函数体里面使用了变量x。该变量由运行环境提供。

现在问题就来了,由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。

var f = function () {
  console.log(this.x);
}
ログイン後にコピー

上面代码中,函数体里面的this.x就是指当前运行环境的x

var f = function () {
  console.log(this.x);
}

var x = 1;
var obj = {
  f: f,
  x: 2,
};

// 单独执行
f() // 1

// obj 环境执行
obj.f() // 2
ログイン後にコピー

上面代码中,函数f在全局环境执行,this.x指向全局环境的x

obj环境执行,this.x指向obj.x

rrreee

この違いの理由は、 this キーワードが関数本体内で使用されているためです。多くの教科書では、this が関数が実行される環境を指すと説明されています。 obj.foo() の場合、fooobj 環境で実行されるため、thisobj を指します。 ; foo() の場合、foo はグローバル環境で実行されるため、this はグローバル環境を指します。したがって、両者の経営成績は異なります。

🎜この説明は正しいですが、なぜそうなるのか教科書には書かれていないことがよくあります。言い換えれば、関数の実行環境はどのように決定されるのでしょうか?たとえば、なぜ obj.foo()obj 環境で実行され、一度 var foo = obj.foo, foo () はグローバル環境で実行されますか? 🎜🎜この記事ではこのようなJavaScriptの処理原理を解説していきます。これを理解すると、this の役割を完全に理解できるようになります。 🎜🎜2. メモリのデータ構造🎜🎜 JavaScript 言語が this の設計になっている理由は、メモリ内のデータ構造に関係しています。 🎜🎜rrreee🎜🎜上記のコードは、オブジェクトを変数 obj に割り当てます。 JavaScript エンジンは、まずメモリ内にオブジェクト { foo: 5 } を生成し、次にこのオブジェクトのメモリ アドレスを変数 obj に割り当てます。 🎜🎜js イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)🎜🎜つまり、変数objはアドレス(参照)です。後で obj.foo を読み取りたい場合、エンジンはまず obj からメモリ アドレスを取得し、次にそのアドレスから元のオブジェクトを読み取り、その foo プロパティ。 🎜🎜元のオブジェクトは辞書構造に保存され、各属性名は属性説明オブジェクトに対応します。たとえば、上記の例の <code>foo 属性は、実際には次の形式で保存されます。 🎜🎜🎜🎜rrreee🎜🎜注意の場合、foo 属性の値は、属性説明オブジェクトの value 属性に格納されます。 🎜🎜3. 関数 🎜🎜 この構造は非常に明確ですが、問題は属性の値が関数である可能性があることです。 🎜🎜rrreee🎜🎜このとき、エンジンは関数をメモリに個別に保存し、関数のアドレスを foo 属性の value 属性に割り当てます。 。 🎜🎜🎜🎜rrreee🎜🎜期限関数は単一の値であるため、さまざまな環境 (コンテキスト) で実行できます。 🎜🎜rrreee🎜🎜4. 環境変数🎜🎜JavaScript では、関数本体内で現在の環境の他の変数を参照できます。 🎜🎜rrreee🎜🎜 上記のコードでは、変数 x が関数本体で使用されています。この変数はランタイム環境によって提供されます。 🎜🎜ここで問題が発生します。関数はさまざまな実行環境で実行できるため、関数本体内に現在の実行環境 (コンテキスト) を取得するメカニズムが必要です。したがって、this が表示されるのは、関数本体内の関数の現在の実行環境を参照することです。 🎜🎜rrreee🎜🎜 上記のコードでは、関数本体の this.x は、現在の実行環境の x を参照しています。 🎜🎜rrreee🎜🎜 上記のコードでは、関数 f がグローバル環境で実行され、 this.x はグローバル環境の x を指します。環境。 🎜🎜🎜🎜in obj 環境の実行、this.xobj.x を指します。 🎜🎜🎜🎜

この記事の冒頭で挙げた質問に戻りますが、obj.foo()是通过obj找到foo,所以就是在obj环境执行。一旦var foo = obj.foo,变量foo就直接指向函数本身,所以foo() はグローバル環境で実行されます。

関連する推奨事項:

js でこれを使用する方法

これのこれは何を意味しますか?

以上がjs イベントの this は何を表しますか? js での this の使用法の詳細な説明 (使用例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート