JavaScriptにおけるこのポインティング問題の詳細な説明

JavaScriptにおけるこのポインティング問題の詳細な説明

序文

JS の this ポインターは、初心者にとって常に頭痛の種でした。今日は、これが地面に落ちたときに何が起こったのかを見て、これが指し示す原理について詳しく話して、これが指し示すことについてこれ以上心配しなくて済むようにしましょう。

導入

まず、これが JavaScript 言語のキーワードであることは誰もが知っています。

これは、関数の実行時に自動的に生成され、関数内でのみ使用できる内部オブジェクトを表します。この値は、関数が使用される場所に応じて変化します。ただし、一般的な原則として、関数が定義されているときには this の方向は決定できません。関数が実行されたときにのみ、 this が実際に指しているオブジェクトを決定できます。実際、 this は最終的に、それが配置されている関数を呼び出すオブジェクトを指します。 それでは、この問題を段階的に検討してみましょう。

1つを探索

関数a() {
  var user = "蒸し鯉";
  console.log(this.name); //未定義
  console.log(this); //ウィンドウ
 }
 ();
 window.a(); // 2つの結果は同じです

上で述べたように、これは最終的に、それが配置されている関数を呼び出すオブジェクトを指します。ここで、 a は実際には window オブジェクトによって指されています。

探索2

var obj = {
  名前:「蒸しアコウ」
  f1: 関数() {
   console.log(this.name); //蒸しコイ}
 };
 obj.f1();

関数が定義されているときには this の方向を決定できないことを再度強調することが重要です。関数が実行されたときにのみ、this が指している対象を決定できます。この例では、this が配置されている f1 関数は obj オブジェクトによって呼び出されるため、ここで this は obj オブジェクトを指しています。

探索3

これを完全に理解したい場合は、次の例を見る必要があります。

var obj = {
  a: 5,
  b: {
   10,
   fn:関数(){
    コンソールログ(this.a); //10
   }
  }
 };
 obj.b.fn();

これは、最終的には、それが配置されている関数を呼び出すオブジェクトを参照するという意味ではないでしょうか?なぜこれは obj オブジェクトを指していないのでしょうか?

ここで 3 つの点を追加する必要があります。

  1. 関数に this があっても、親オブジェクトによって呼び出されない場合は、this は window を参照します。
  2. 関数に this があり、前のレベルのオブジェクトによって呼び出される場合、 this は前のレベルのオブジェクトを参照します。
  3. 関数に this があり、複数のオブジェクトが含まれている場合、関数が最も外側のオブジェクトによって呼び出されても、this はその 1 レベル上のオブジェクトのみを指します。

これを見て、皆さんは this のポイントの原理を基本的に理解したと思います。もう一度繰り返しますが、関数が定義されているときには this のポイントは決定できません。関数が実行されたときにのみ、 this が実際に誰を指しているかを判断できます。実際、 this は最終的に、それが配置されている関数を呼び出すオブジェクトを指します。

これにはいくつかの異なる使用シナリオがあります

コンストラクタ(新しいキーワード)の場合

関数 Student() {
  this.name = '蒸しファットヘッドフィッシュ';
 }
 var s1 = 新しい学生();
 console.log(s1.name); // 蒸しコイ

オブジェクト s1 が関数 Student 内の名前を指すことができる理由は、new キーワードによって this のポインターがオブジェクト s1 を指すように変更できるためです。

// new キーワードの実行プロセス 1. 関数本体に空のオブジェクトを作成します。
 2. 現在の this がこの空のオブジェクトを指すようにします。
 3. これを介して、現在空のオブジェクトにキーと値のペアを追加します。
 4. すべてのキーと値のペアを外部変数に追加されたオブジェクトを返します。

タイマー内のthisポインタ

var 数値 = 0;
 関数Obj() {
  数値 = 1;
  this.getNum1 = 関数(){
   コンソールにログ出力します。
  };
  this.getNum2 = 関数(){
   setInterval(関数() {
    コンソールにログ出力します。
   }, 1000);
  };
 }
 var o = 新しいObj();
 o.getNum1();//1 (o.num)
 o.getNum2();//0 (ウィンドウ番号)

o.getNum2()の値が 0 である理由は、 this wi windowを指しているためです。説明するために、 this の指し示す原則を取り上げてみます。関数が定義されているときには、 thisの指し示す先は決定できません。関数が実行されたときにのみ、 this実際に指している先を決定できます。実際、 this最終的に、それが配置されている関数を呼び出すオブジェクトを指します。

解決策: this.numが配置されている関数は、タイマーsetInterval内のfunction () { console.log(this.num);}です。 this ポインティング原則によれば、関数が実行されると、 this はその親オブジェクトを指します。 setIntervalあり、 setInterval windowによって指されているため、 this windowを指します。

callapplybind方向を変える

var 数値 = 0;
 関数Obj() {
  数値 = 1;
  this.getNum1 = 関数(){
   コンソールにログ出力します。
  };
  this.getNum2 = 関数(){
   setInterval(関数() {
    コンソールにログ出力します。
   }.bind(this), 1000);//bind を使用して this をこの関数にバインドします};
 }
 var o = 新しいObj();
 o.getNum1();//1 (o.num)
 o.getNum2();//1 (o.num)
 

説明する:

bind() メソッドは Function.prototype のメソッドです。バインドされた関数によって呼び出されると、bind メソッドは新しい関数を作成し、最初のパラメータを新しい関数のランタイム this として使用します。

原則によれば:

bindメソッドを使用する前: 呼び出されたとき: this.num 、それが配置されている関数を呼び出すオブジェクト、つまりwindow.setTimeoutオブジェクトを指します。 bindメソッドを使用した後、呼び出されると、元のthisgetSum2関数 (新しいthisが配置されている関数) を呼び出すオブジェクトにリダイレクトされます。ここで、コンストラクターはnewを通じて呼び出されるため、 o オブジェクトを指します。

このような状況では、 bindメソッドがより一般的に使用されます。もちろん、代わりにcallまたはapplyメソッドを使用した場合も結果は正しいですが、 callapplyメソッドは呼び出し後すぐに実行されるため、遅延効果はなく、タイマーは意味をなさなくなります。

上記は、JavaScript の this ポイントの問題の詳細な説明です。JavaScript の this ポイントの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScriptは関連する問題とその修正方法を示しています
  • JavaScript の this ポイントとバインディングの詳細な説明
  • JavaScriptでこれについて私が理解していること
  • JavaScriptのこのキーワードは一般的なケース分析を指します
  • JavaScriptにおけるthisのポイント問題についての簡単な説明
  • JavaScriptにおけるthisの変更についての簡単な説明
  • JavaScriptは関連する原則と例を示しています
  • JavaScriptの詳しい説明 このポインティング問題
  • JS で「this」を処理する簡単な方法をいくつか簡単に説明します
  • js での this のポイント問題の詳細な説明

<<:  MySQL 最適化接続最適化

>>:  Linux で lvm 論理ボリューム パーティションのサイズを調整するチュートリアル (xfs や ext4 などのさまざまなファイル システム用)

推薦する

入力ボックスのオートコンプリート機能をオフにする

これで、autocomplete と呼ばれる input の属性を使用できるようになりました。オート...

CSS変数var()の使い方を理解する必要があります

Web プロジェクトがどんどん大きくなると、CSS は天文学的な大きさと複雑さを増します。この問題を...

Docker Compose を使用して ELK を迅速にデプロイする (テスト済みで効果的)

目次1. 概要1.1 定義1.2 機能説明2. ELKを展開する2.1 ディレクトリとファイルを作成...

MySQL PHP 構文の簡単な分析

まずcharAt関数の基本的な構文を見てみましょう文字 = str.charAt(インデックス) c...

CSS3+HTML5+JSでブロックの縮小・拡大アニメーション効果を実現

最近、あるプロジェクトに取り組んでいたとき、自分のプロジェクトでは CSS3 のアニメーション技術を...

MySQLカスタム関数の原理と使用法の分析

この記事では、例を使用して MySQL カスタム関数の原理と使用方法を説明します。ご参考までに、詳細...

docker に nacos をインストールしてデータベースを構成する詳細なチュートリアル

環境の準備 Docker環境 MySQL 5.7 (公式イメージはmysql8をサポートしていません...

JavaScript の一般的なステートメント ループ、判定、文字列から数値

目次1. スイッチ2. whileループ3. Do/Whileループ3. 文字列を数値に変換する1....

Tomcatサーバーのセキュリティ設定方法

Tomcat は、Java Community Process を通じて Sun が開発した、広く使...

Vue+Websocketはチャット機能を実装するだけです

この記事では、チャット機能を簡単に実装するためのVue+Websocketの具体的なコードを参考まで...

HTMLでカスタムタグを使用する方法

カスタム タグは XML ファイルと HTML ファイルで自由に使用できますが、いくつか注意すべき点...

Linux での JDK と Tomcat のアップロードと設定に関する詳細なチュートリアル

準備1. 仮想マシンを起動する2. gitツールルートアカウントでログインルートアカウントを使用して...

フロントエンドは画像を遅延ロードする方法を知っている必要があります(3つの方法)

目次1. 遅延読み込みとは何ですか? 2. 遅延読み込みを実装する🌄: 2.1 最初の方法: 2.2...

React のクラスからフックへの移行

目次リアクトフック序文なぜフックなのか?クラス関数クラスとフックの比較フックはコンポーネントの状態を...

Tomcat の構成と最適化ソリューションの詳細な説明

サービス.xml Server.xml 構成ファイルは、コンテナー全体を構成するために使用されます。...