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

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

序文

信じてください。この記事の 7️⃣ ステップを覚えておけば、JS の this リファレンスを完全にマスターできます。

まず、式を暗唱します: 矢印関数、新規、バインド、適用して呼び出し、オブジェクト、直接呼び出し、関数内ではありません。

式の順序に従って、前のシナリオのいずれかが満たされている限り、これがどこを指しているかを判断できます。

では、数式の順番に詳しく説明していきます。記事内のサンプルコードはすべてChromeコンソールで実行されています。

記事の最後には、学習成果をテストするための練習問題が用意されています。ぜひ試してみてください。

1. 矢印関数

矢印関数は、this が変更されないため最初にランク付けされます。したがって、現在の関数が矢印関数である限り、他のルールを確認する必要はありません。

矢印関数の this は、作成されたときの外側の this への参照です。ここで重要なポイントが 2 つあります。

  1. 矢印関数が作成されると、その this ポインターが決定されます。
  2. 矢印関数内の this は外側の this を参照します。

したがって、矢印関数の this を知るには、まず外側の this の方向を知る必要があり、外側の層で 7 段階の式を継続的に適用する必要があります。

2. 新しい

new キーワードを使用して関数が呼び出される場合、関数内の this は JS によって作成された新しいオブジェクトである必要があります。

読者は、「矢印関数が new キーワードを使用して呼び出された場合、矢印関数の this は変更されるのだろうか?」と疑問に思うかもしれません。

コンソールで試してみましょう。

関数 = () => {}
new func() // エラーをスローする

コンソールからわかるように、矢印関数はコンストラクターとして使用できないため、new で実行することはできません。

3. バインドする

bind は Function.prototype.bind() を参照します。

複数回バインドする場合、最初のバインドの値のみが認識されます

エラーが発生しやすいポイント

関数func() {
  console.log(これ)
}

関数bind(1).bind(2)() // 1

これは矢印関数では変更されません

バインドして新規

エラーが発生しやすいポイント

関数func() {
  console.log(this, this.__proto__ === func.prototype)
}

バインド関数 = func.bind(1)
new boundFunc() // オブジェクトが true の場合、式 2 が優先されます

4. 申し込んで電話する

apply() と call() の最初のパラメータは次のとおりです。違いは、apply を呼び出す場合、実際のパラメータが配列に配置され、call を呼び出す場合、実際のパラメータがコンマで区切られることです。

これは矢印関数では変更されません

エラーが発生しやすいポイント

関数 = () => {
  // ここで this は外側の this を指しており、式 7 の「関数内ではない」を参照してください。
  console.log(これ)
}

func.apply(1) // ウィンドウ、式1が優先される

これはバインド関数では変更されません

エラーが発生しやすいポイント

関数func() {
  console.log(これ)
}

バインド関数 = func.bind(1)
boundFunc.apply(2) // 1、式3が優先される

5. 帯点(オブジェ)

関数func() {
  コンソールログ(this.x)
}

オブジェクト = { x: 1 }
obj.func = 関数
obj.func() // 1

ここで、矢印関数とバインド関数の優先度が高いことを示すためにコードを使用する必要はありません。興味がある場合は、自分で試してみてください。

6. 直接通話

関数が前のシナリオを満たさず、直接呼び出される場合、これはグローバル オブジェクトを指します。ブラウザ環境ではグローバルオブジェクトはWindowであり、Node.js環境ではGlobalです。

簡単な例から始めましょう。

関数func() {
  console.log(これ)
}

func() // ウィンドウ

外側の層の outerFunc が紛らわしい目的を果たす複雑な例を見てみましょう。

関数outerFunc() {
  console.log(これ) // { x: 1 }

  関数func() {
    console.log(this) // ウィンドウ
  }

  関数()
}

外側の関数をバインドします({ x: 1 })()

7. 関数内ではない

関数に含まれないシナリオは、ブラウザの <script /> タグまたは Node.js モジュール ファイルに分割できます。

  1. <script /> タグでは、これは Window を参照します。
  2. Node.js モジュール ファイルでは、これはモジュールのデフォルトのエクスポート オブジェクト (module.exports) を参照します。

非厳密モード

厳密モードは ES5 で導入されました。 ES5 仕様より前、つまり非厳密モードでは、これを undefined または null にすることはできません。したがって、**非厳密モードでは、上記の 7 つの手順を経て、 this が undefined または null を指していると判断された場合、 this はグローバル オブジェクトを指します。 **ブラウザ環境ではグローバルオブジェクトはWindow、Node.js環境ではGlobalです。

たとえば、次のコードでは、非厳密モードでは、これはグローバル オブジェクトを参照します。

関数a() {
  console.log("関数 a:", this)
  ;(() => {
    console.log("矢印関数: ", this)
  })()
}

()

a.bind(null)()

a.bind(未定義)()

a.bind().bind(2)()

適用()

非厳密モードでの実行結果は次のとおりです。

厳密モードでは、比較のために同じコードを実行します。厳密モードで実行するには、すべてのコードを一度にコンソールにコピーして貼り付けることを忘れないでください (最初の行の「use strict」が次のコードに適用されるため)。

「厳密な使用」

関数a() {
  console.log("関数 a:", this)
  ;(() => {
    console.log("矢印関数: ", this)
  })()
}

()

a.bind(null)()

a.bind(未定義)()

a.bind().bind(2)()

適用()

厳密モードで実行した結果は次のようになります。

7 ステップの式は、厳密モードと非厳密モードの両方で完了しますが、非厳密モードでは null または undefined がグローバル オブジェクトに変換される点が異なります。そのため、これをヒントに含めませんでした。

復習問題

まず式を暗唱し、次に「矢印関数、新規、バインド、適用して呼び出す、オブジェクト、直接呼び出し、関数内ではない」という質問をします。

1. 次のコードを実行した後、func.count の値は何ですか?

関数 func(num) {
  this.count++
}

関数カウント = 0
関数(1)

答え

func.count は 0 です。

式によれば、func() が呼び出される場合は、6 番目のカテゴリ「直接呼び出し」に属します。非厳密モードでは、これはグローバル オブジェクトを参照します。これは func とは関係がないので、func.count は変更されません。とても簡単です。

2. 次の矢印関数は誰を指していますか?

オブジェクト = {
  関数() {
    const arrowFunc = () => {
      コンソールログ(this._name)
    }

    戻り矢印関数
  },

  _name: "オブジェクト",
}

obj.func()()

関数 = obj.func
関数()()

obj.func.bind({ _name: "newObj" })()()

obj.func.bind()()()

obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()

答え

// オブジェクト
// 未定義
//新しいオブジェクト
// 未定義
// バインドオブジェクト

とても簡単ですよね?習得を諦めていませんか?

要約する

これで、JavaScript の this ポイントの問題に関するこの記事は終わりです。js の this ポイントに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • JSの矢印関数におけるこのポイントの詳細な説明
  • JavaScriptの原理と方向性
  • JS にこれがあるのはなぜですか?
  • このリファレンスとJavaScriptのカスタムプロパティの詳細な説明
  • JavaScript における this ポイントの問題の詳細な説明
  • 関数の分類の詳細な説明とJavascriptでのこのポイントの例
  • JavaScript関数におけるこのポイントの問題の詳細な説明
  • JavaScriptの詳細な分析と方向の変更方法

<<:  データベース接続プール Druid の使用手順

>>:  https ウェブサイトを展開し、Nginx でアドレス書き換えを構成するための詳細な手順

推薦する

JavaScript配列についてさらに詳しく知るのに役立つ記事

目次1. 配列の役割: 2. 配列の定義: 1. コンストラクタを通じて配列を作成する2. リテラル...

古い Vue プロジェクトに Vite サポートを追加する方法

1. はじめに会社のプロジェクトを引き継いで2年になります。今では毎回プロジェクトを起動するのに1分...

VMware仮想マシンにLinux(CentOS)をインストールするための詳細な構成手順

CentOS7をダウンロード私がダウンロードしたイメージはCentOS-7-x86_64-DVD-1...

MySQL 最適化 Zabbix パーティション最適化

zabbix を利用する上での最大のボトルネックはデータベースです。zabbix のデータストレージ...

JavaScript フレームワーク デザイン パターンの詳細な説明

目次動画最優秀選手ムヴヴムVueのソーススパ mpa要素を作成するクラス要約する動画 Model(模...

IE8でラベルの背景画像が表示されない問題の解決方法

今日、ちょっとした問題に遭遇し、長い間苦労しました。そのことを皆さんにシェアしたいと思います。 a ...

XHTMLタグには終了タグがある

<br />オリジナルリンク: http://www.dudo.org/article....

MySql マスタースレーブレプリケーションの実装原理と構成

データベースの読み取りと書き込みの分離は、トラフィック量の多い大規模システムやインターネット アプリ...

共通要素のデフォルトのマージンとパディング値に関する議論

今日は、さまざまなブラウザでのデフォルト要素のマージン値が何であるかという問題について説明しました。...

単一テーブルのMySQLバックアップとリストアに関する簡単な説明

A. MySQLバックアップツールxtrabackupのインストール1. Percona 公式 xt...

JavaScript スタイル オブジェクトと CurrentStyle オブジェクトのケース スタディ

1. スタイルオブジェクトスタイル オブジェクトは単一のスタイル宣言を表し、スタイルが適用されている...

MySQL/MariaDB でピボット テーブルを実装する方法のサンプル コード

前回の記事では、Oracle でピボット テーブルを実装するいくつかの方法を紹介しました。今日は、同...

Docker インストール tomcat dubbo-admin インスタンス スキル

1. tomcatイメージをダウンロードする docker pull tomcat:8.5.29 2...

TypeScript のマップされた型とより優れたリテラル型推論について説明します。

目次概要マップされた型を使用して Object.freeze() を構築するマッピングタイプの構文は...

乱数、文字列、日付、検証コード、UUIDを生成するMySQLメソッド

目次乱数を生成する0から1までの乱数を生成する指定された範囲内で乱数を生成します6桁のモバイル認証コ...