ホームページ ウェブフロントエンド jsチュートリアル これに関連する入門、JS での適用、呼び出し、バインド

これに関連する入門、JS での適用、呼び出し、バインド

Sep 20, 2017 am 09:28 AM
apply bind javascript

JS の This、apply、call、bind は典型的な面接の質問です。this と call、apply、bind の方向の違いを理解することが最善です。 Script House の編集者に従って、この知識を学び、応募し、電話をかけ、バインドしましょう

これも典型的な面接の質問です~/(ㄒoㄒ)/~~ これは、ES5 にある多くの落とし穴の 1 つでもあります。 ES6 これにより発生するエラーを大幅に回避できる可能性がありますが、一部の古いコードを保守するには、this のポイントと call、apply、bind の違いを理解することが最善です。

this

のポイント 実際、ES5 では、this のポイントは常に 1 つの原則に従います。これは、常に最後に呼び出したオブジェクトを指します。さあ、私の後に 3 回読んでください。そのオブジェクト、this は常にそれを呼び出した最後のオブジェクトを指し、this は常にそれを呼び出した最後のオブジェクトを指します。この文を覚えておいてください。半分はすでに知っています。

最も単純な例を見てみましょう:

例 1:


 var name = "windowsName";
 function a() {
  var name = "Cherry";
  console.log(this.name);   // windowsName
  console.log("inner:" + this); // inner: Window
 }
 a();
 console.log("outer:" + this)   // outer: Window
ログイン後にコピー

ログが windowsName である理由は誰もが知っていると思います。なぜなら、今の文によると、「これは常に最後に呼び出したログを指しているからです」 it Object" で、a が a(); と呼ばれる最後の場所を見てみましょう。前に呼び出されなかったオブジェクトは、window.a() と同等のグローバル オブジェクト ウィンドウです。厳密モードを使用していないことに注意してください。ここで、厳密モードが使用されている場合、グローバル オブジェクトが未定義である場合、「Uncaught TypeError: Cannot read property 'name' of unknown」というエラーが報告されます。

この例をもう一度見てください:

例 2:


var name = "windowsName";
 var a = {
  name: "Cherry",
  fn : function () {
   console.log(this.name);  // Cherry
  }
 }
 a.fn();
ログイン後にコピー

この例では、関数 fn がオブジェクト a によって呼び出されるため、出力される値は a の name の値です。もう少し分かりやすくなりましたか~

少し変更を加えてみましょう:

例 3:


var name = "windowsName";
 var a = {
  name: "Cherry",
  fn : function () {
   console.log(this.name);  // Cherry
  }
 }
 window.a.fn();
ログイン後にコピー

ここに Cherry が表示されている理由も、先ほどの文のせいです。「これは常に最後に呼び出したオブジェクトを指します」 it” ” の場合、最終的にそれを呼び出したオブジェクトは依然としてオブジェクト a です。

もう一度この例を見てみましょう:

例 4:


 var name = "windowsName";
 var a = {
  // name: "Cherry",
  fn : function () {
   console.log(this.name);  // undefined
  }
 }
 window.a.fn();
ログイン後にコピー

なぜここに unfineed が出力されるのでしょうか?これは、先ほど説明したように、 fn がオブジェクト a によって呼び出されるためです。これは、 fn の内部 this がオブジェクト a であり、 name がオブジェクト a で定義されていないため、ログ内の this.name の値が undefine であるためです。

この例は、さらに次のことを示しています。 fn を最後に呼び出したオブジェクトは a であるため、 this は常にそれを最後に呼び出したオブジェクトを指します。そのため、a に name 属性がない場合でも、次の this.name の検索は続行されません。前のオブジェクトですが、未定義を直接出力します。

もっと分かりにくい例を見てみましょう:

例 5:


 var name = "windowsName";
 var a = {
  name : null,
  // name: "Cherry",
  fn : function () {
   console.log(this.name);  // windowsName
  }
 }
 var f = a.fn;
 f();
ログイン後にコピー

ここで疑問があるかもしれませんが、なぜ Cherry ではないのでしょうか? これは、オブジェクトの fn メソッドが変数 f に割り当てられているためです。 、呼び出しはありません、そして私の後にこの文を読んでください: 「これは常にそれを最後に呼び出したオブジェクトを指します。」 f が今呼び出されなかったので、fn() は最終的にまだウィンドウによって呼び出されています。したがって、これはウィンドウを指します。

上記の 5 つの例から、es5 では、this のポイントは常に最後に呼び出したオブジェクトを指すことがわかります。

別の例を見てみましょう:

例6:


 var name = "windowsName";
 function fn() {
  var name = 'Cherry';
  innerFunction();
  function innerFunction() {
   console.log(this.name);  // windowsName
  }
 }
 fn()
ログイン後にコピー

今読んだら、なぜこれが起こっているのか理解できるはずです(o゚▽゚)o。

thisの点を変更する方法

thisの点を変更する以下の方法をまとめました:

ES6のarrow関数を使う

関数内で_this = thisを使う

apply, call、bind

new はオブジェクトをインスタンス化します

例 7:


var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   },100);
  }
 };
 a.func2()  // this.func1 is not a function
ログイン後にコピー

アロー関数が使用されていない場合、setTimeout を呼び出す最後のオブジェクトが window であるため、エラーが報告されますが、setTimeout が存在しないためです。 func1関数はありません。

このポインタを変更するこのセクションでは、デモとしてこの例を変換します。

アロー関数

ご存知のとおり、ES6 のアロー関数は、ES5 でこれを使用する場合の落とし穴を回避できます。アロー関数の this は、関数が実行されるときではなく、関数が定義されるときに常に this を指します。アロー関数は次の文を覚えておく必要があります。「アロー関数には this バインディングがありません。その値はスコープ チェーンを検索して決定する必要があります。アロー関数がアロー関数以外の関数に含まれている場合、このバインディングは次のようになります。」最も近い非矢印関数は this、それ以外の場合は未定義です。」

例 8:


 var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   setTimeout( () => {
    this.func1()
   },100);
  }
 };
 a.func2()  // Cherry
ログイン後にコピー

関数内で _this = this を使用します

ES6 を使用しない場合は、このメソッドが最も簡単でエラーのない方法です。最初にこの関数を呼び出します。オブジェクトは次のとおりです。変数 _this に保存され、その後、この _this が関数で使用されるため、_this は変更されません。

例 9:


 var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   var _this = this;
   setTimeout( function() {
    _this.func1()
   },100);
  }
 };
 a.func2()  // Cherry
ログイン後にコピー

这个例子中,在 func2 中,首先设置 var _this = this;,这里的 this 是调用 func2 的对象 a,为了防止在 func2 中的 setTimeout 被 window 调用而导致的在 setTimeout 中的 this 为 window。我们将 this(指向变量 a) 赋值给一个变量 _this,这样,在 func2 中我们使用 _this 就是指向对象 a 了。

使用 apply、call、bind

使用 apply、call、bind 函数也是可以改变 this 的指向的,原理稍后再讲,我们先来看一下是怎么实现的:

使用 apply

例 10:


 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.apply(a),100);
  }
 };
 a.func2()   // Cherry
ログイン後にコピー

使用 call

例 11:


 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.call(a),100);
  }
 };
 a.func2()   // Cherry
ログイン後にコピー

使用 bind

例 12:


var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.bind(a)(),100);
  }
 };
 a.func2()   // Cherry
ログイン後にコピー

apply、call、bind 区别

刚刚我们已经介绍了 apply、call、bind 都是可以改变 this 的指向的,但是这三个函数稍有不同。

在 MDN 中定义 apply 如下;

apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数

语法:


fun.apply(thisArg, [argsArray])
ログイン後にコピー

thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。

argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。

apply 和 call 的区别

其实 apply 和 call 基本类似,他们的区别只是传入的参数不同。

call 的语法为:


fun.call(thisArg[, arg1[, arg2[, ...]]])
ログイン後にコピー

所以 apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。

例 13:


var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.apply(a,[1,2])  // 3
ログイン後にコピー

例 14:


var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.call(a,1,2)  // 3
ログイン後にコピー

bind 和 apply、call 区别

我们先来将刚刚的例子使用 bind 试一下


 var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.bind(a,1,2)
ログイン後にコピー

我们会发现并没有输出,这是为什么呢,我们来看一下 MDN 上的文档说明:

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

所以我们可以看出,bind 是创建一个新的函数,我们必须要手动去调用:


var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.bind(a,1,2)()   // 3
ログイン後にコピー

以上がこれに関連する入門、JS での適用、呼び出し、バインドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

See all articles