JavaScript 関数呼び出し、適用、バインド メソッドのケース スタディ

JavaScript 関数呼び出し、適用、バインド メソッドのケース スタディ

要約する

1. 類似点

  1. どちらも、ターゲット関数が実行されると内部の this ポインターを変更できます。
  2. メソッドの最初のパラメータは、関数の実行時に内部の this 値を指定するために使用されます。
  3. 任意の数のパラメータをターゲット関数に渡すことをサポート
  4. メソッドの最初のパラメータに値を渡さない場合、または undefined または null を渡す場合、JavaScript の通常モードでは、ターゲット関数内の this は window オブジェクトを指し、厳密モードでは、それぞれ undefined または null を指します。

2. 違い

  1. apply() メソッドは 2 つのパラメータを受け入れますが、call() メソッドと bind() メソッドは複数のパラメータを受け入れます。
  2. apply() メソッドがターゲット関数にパラメータを渡す場合、メソッドの 2 番目のパラメータとしてパラメータ配列または引数オブジェクトを渡すだけで済みますが、call() メソッドと bind() メソッドでは、メソッドのパラメータの後にパラメータを 1 つずつリストする必要があります。
  3. call() メソッドと apply() メソッドが呼び出されると、ターゲット関数はすぐに実行されますが、bind() メソッドは実行されません。bind() メソッドは、ターゲット関数のコピーである新しい関数を返します。関数内の this は、bind() メソッドの最初のパラメータを指します。その後に新しい関数を実行することは、ターゲット関数を実行することと同じです。
  4. bind() メソッドのみが関数カリー化を実装しているため、ターゲット関数にパラメータを 2 回渡すことができます。

call() メソッド

  1. call() メソッドを呼び出すと、ターゲット関数がすぐに実行され、関数内の this の参照が変更されます。これはメソッドの最初のパラメータを指し、1 つずつリストされたパラメータは、ターゲット関数のパラメータとして 1 つずつ渡されます。
  2. 冒頭の要約の最後のポイントの例は次のとおりです。
/* 通常モード */

obj = {
  合計(a, b) {
    console.log(これ)
    a + bを返す
  }
}

// sum 関数の apply メソッドと bind メソッドを実行します。出力される内容は以下のようになります。obj.sum.call() // ウィンドウを印刷
obj.sum.call(undefined, 1, 2) // 印刷ウィンドウ
obj.sum.call(null, 1, 2) // 印刷ウィンドウ
/* 厳密モード */
「厳密な使用」

// sum関数のapplyメソッドとbindメソッドを実行し、以下のように出力します。obj.sum.call() // undefinedを出力します。
obj.sum.call(undefined, 1, 2) // undefined と表示される
obj.sum.call(null, 1, 2) // null を出力します

シミュレーションの実装

1. 要点

  1. myCall() メソッドが Function プロトタイプ オブジェクトに追加されます。ターゲット関数がこのメソッドを呼び出すと、myCall() メソッド内の this がターゲット関数を指します。
  2. ターゲット関数をコンテキスト オブジェクトのメソッドとして実行し、ターゲット関数内の this がコンテキスト オブジェクトを指すようにします。 。
  3. コンテキストオブジェクトからターゲット関数を削除します
  4. スプレッド演算子を使用して、ターゲット関数に渡されたパラメータを処理します。

2. call()、apply()、bind() メソッドのシミュレーション実装において、最初のパラメータが渡されない場合や undefined または null が渡された場合、ここでは JS 通常モードと厳密モードで統一された処理が行われ、つまり、対象関数内の this は window オブジェクトを指します。

3. コードは次のとおりです

Function.prototype.myCall = function (コンテキスト、...引数) {
  コンテキスト === 未定義 || コンテキスト === null の場合 {
    コンテキスト = ウィンドウ
  }
  // 次の行はコアコードです context.fn = this
  const 結果 = context.fn(...args)
  コンテキストを削除する.fn
  結果を返す
}

obj1 = {
  基本数: 1,
  合計(a, b) {
    console.log(これ)
    this.basicNum + a + b を返す
  }
}
obj2 = {
  基本数: 9
}
コンソールログ(obj1.sum.call(obj2, 2, 3)) // 14
コンソールログ(obj1.sum.myCall(obj2, 2, 3)) // 14

apply() メソッド

apply() メソッドを呼び出すと、ターゲット関数が直ちに実行され、関数内の this の参照が変更されます。これはメソッドの最初のパラメータを指します。2 番目のパラメータはパラメータ配列または引数オブジェクトです。各配列要素または引数オブジェクトによって表される各パラメータは、ターゲット関数のパラメータとして 1 つずつ渡されます。

シミュレーションの実装

1.要点

  1. myApply() メソッドが Function プロトタイプ オブジェクトに追加されます。ターゲット関数がこのメソッドを呼び出すと、myApply() メソッド内の this がターゲット関数を指します。
  2. ターゲット関数をコンテキスト オブジェクトのメソッドとして実行し、ターゲット関数内の this がコンテキスト オブジェクトを指すようにします。
  3. コンテキストオブジェクトからターゲット関数を削除します
  4. スプレッド演算子を使用して、ターゲット関数に渡されたパラメータを処理します。

2. コードは次のとおりです

Function.prototype.myApply = 関数 (コンテキスト、引数) {
  コンテキスト === 未定義 || コンテキスト === null の場合 {
    コンテキスト = ウィンドウ
  }
  // 次の行はコアコードです context.fn = this
  const 結果 = context.fn(...args)
  コンテキストを削除する.fn
  結果を返す
}

コンソール.log(obj1.sum.apply(obj2, [2, 3])) // 14
コンソール.log(obj1.sum.myApply(obj2, [2, 3])) // 14

bind() メソッド

  1. bind() メソッドを呼び出すと、新しい関数 (ターゲット関数のコピー) が返されます。関数内の this は、メソッドの最初のパラメータを指します。1 つずつリストされたパラメータは、ターゲット関数のパラメータとして 1 つずつ渡されます。その後に新しい関数を実行することは、ターゲット関数を実行することと同じです。
  2. bind() メソッドは関数のカリー化を実装しているため、ターゲット関数にパラメータを 2 回渡すことができます。最初のパラメータは bind() メソッドの最初のパラメータの後にリストされ、2 番目のパラメータは新しい関数にリストされます。

シミュレーションの実装

1. 要点

  1. myBind() メソッドが Function プロトタイプ オブジェクトに追加されます。ターゲット関数がこのメソッドを呼び出すと、myBind() メソッド内の this がターゲット関数を指します。
  2. ターゲット関数をコンテキスト オブジェクトのメソッドとして実行し、ターゲット関数内の this がコンテキスト オブジェクトを指すようにします。
  3. コンテキストオブジェクトからターゲット関数を削除します
  4. スプレッド演算子... を使用して、ターゲット関数に渡される最初のパラメータと後続のパラメータを処理します。

2. コードは次のとおりです

Function.prototype.myBind = function (context, ...initArgs) {
  コンテキスト === 未定義 || コンテキスト === null の場合 {
    コンテキスト = ウィンドウ
  }
  // この値をキャッシュする const _this = this
  関数を返す (...引数) {
    // 次の行はコアコードです context.fn = _this
    const 結果 = context.fn(...initArgs, ...args)
    コンテキストを削除する.fn
    結果を返す
  }
}

コンソール.log(obj1.sum.bind(obj2, 2)(3)) // 14
コンソール.log(obj1.sum.myBind(obj2, 2)(3)) // 14

関連する知識ポイント

  • JavaScriptにおけるthisの参照について

JavaScript 関数呼び出し、適用、およびバインド メソッドの詳細なケース分析に関するこの記事はこれで終わりです。JavaScript 関数呼び出し、適用、およびバインド メソッドに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • JSの矢印関数におけるこのポイントの詳細な説明
  • JavaScript 関数構文の説明
  • Vue.jsのレンダリング関数の使い方の詳しい説明
  • JavaScript 基礎シリーズ: 関数とメソッド
  • JavaScript CollectGarbage 関数の例
  • JavaScript関数導入の詳しい説明

<<:  Nginx の realip モジュールの使い方の基礎学習

>>:  MySQL のキーとインデックスの違い

推薦する

HTML シンボルからエンティティへのアルゴリズムのチャレンジ

チャレンジ:文字列内の文字 &、<、>、" (二重引用符)、および &...

Nginx ログのカスタマイズとログ バッファの有効化の詳細な説明

序文ウェブサイトのアクセス元をカウントしたい場合は、PHP を使用して情報を取得してデータベースに記...

ウェブサイトのデザインでは色の階層感覚に注意を払う必要があります

最近、私はデザインには階層感覚が必要だと言っています。この階層感覚には、色の重ね合わせや要素の重ね合...

Java は Apache.POI を使用して HSSFWorkbook を Excel にエクスポートします

Apache.POI の HSSFWorkbook を使用して Excel にエクスポートします。具...

Linux スケジュールタスクの関連操作の概要

皆様の参考と操作を容易にするために、様々な主要ウェブサイトを検索し、関連するスケジュールされたタスク...

CSS3 の新しいレイアウト: flex の詳細な説明

Flexの基本概念フレックス レイアウト (フレックスはフレキシブル ボックスの略)、エラスティック...

いくつかの一般的な CSS レイアウト (要約)

まとめこの記事では、次の一般的なレイアウトを紹介します。 3 列レイアウトを実装する方法は多数ありま...

ウェブページ作成によく使われる英語フォント

アリアルArial は、多くの Microsoft アプリケーションとともに配布されるサンセリフ T...

MySQLはOracleシーケンスに似たソリューションを実装しています

MySQLはOracleのようなシーケンスを実装しているOracle は通常、主キー フィールドを処...

HTML を使用して IE8 および IE9 の互換表示モードを無効にするヒント

IE 8 以降では互換モードが追加され、これを有効にすると IE の下位バージョンでレンダリングされ...

Vue3+Element+Tsは、フォームの基本的な検索リセットやその他の機能を実装します

Vue2 の記述スタイルから Vue3 の形式に切り替えると、記述スタイルとコード構造にいくつかの変...

Unicodeの一般的な記号

Unicode は、世界中のすべてのテキストと記号に対応できる国際組織によって開発された文字エンコー...

純粋なCSSでデジタルプラスとマイナスボタンを実装するための最適なソリューション

序文:デジタル加算ボタンと減算ボタンの実装には、次のような多くのソリューションがこれまでに使用されて...

MySQL のデータ削除とデータ テーブル メソッドの例

MySQL でデータやテーブルを削除するのは非常に簡単ですが、削除するとすべてのデータが消えてしまう...

Vue でのルーティングガードの具体的な使用法

目次1. グローバルガード1.1 グローバルフロントガード1.2 グローバルポストルートガード1.3...