JavaScript の Function.prototype.bind メソッドを理解する

高洛峰
リリース: 2017-02-03 13:35:29
オリジナル
1043 人が閲覧しました

初めて Javascript を学ぶときは、関数バインディングについて心配する必要はないかもしれませんが、コンテキスト オブジェクトを別の関数で維持する必要がある場合、多くの人がこの問題に対処するのを見てきました。彼らは皆、最初に割り当てを行います。 this を変数 (self、_this、that など) に変換します。特に var that = this は私がよく見るもので、環境を変更した後でも使用できるようにします。これらはすべて可能ですが、より優れた独自の方法があります。それは、以下で詳しく説明する Function.prototype.bind を使用することです。

パート 1: 解決する必要がある問題

まず以下のコードを見てください

var myObj = {
 
  specialFunction: function () {
 
  },
 
  anotherSpecialFunction: function () {
 
  },
 
  getAsyncData: function (cb) {
    cb();
  },
 
  render: function () {
this.getAsyncData(function () {
      this.specialFunction();
      this.anotherSpecialFunction();
    });
  }
};
 
myObj.render();
ログイン後にコピー

ここでは、最初の 2 つの通常のメソッドを含むオブジェクトを作成したいと思います。3 番目のメソッドは関数を渡すことができます。 in この関数はすぐに実行されます。最後のメソッドは、ここでこれを使用して myObj オブジェクトの getAsyncData メソッドを呼び出し、その後 getAsyncData メソッドに関数を渡します。この関数は引き続きこのオブジェクトの最初の 2 つのメソッドを呼び出します。この時点で、多くの人が実際に問題を確認できます。上記のコードをコンソールに入力すると、次の結果が得られます:

TypeError: this.specialFunction is not a function
ログイン後にコピー

パート 2: 問題の分析

これはオブジェクトの render メソッドで行われます。 myObj オブジェクトを指すため、this.getAsyncData を通じてこのオブジェクト内の関数を呼び出すことができますが、関数をパラメーターとして渡すと、グローバル環境には前のオブジェクトがないため、ここではグローバル環境ウィンドウを指します。メソッドがあるため、エラーが報告されます。

パート 3: 問題を解決するいくつかの方法

そこで、私たちが行う必要があるのは、オブジェクト内の最初の 2 つのメソッドを正しく呼び出すことです。多くの人が使用する方法は、まずオブジェクトの環境でこれを取得して代入することです。これを別の変数に追加すると、以下に示すように、後続の環境で呼び出すことができます。

render: function () {
  var that = this;
  this.getAsyncData(function () {
    that.specialFunction();
    that.anotherSpecialFunction();
  });
}
ログイン後にコピー

このメソッドは実行可能ですが、Function.prototype.bind() を使用すると、コードがより明確になり理解しやすくなります。以下の表示:

render: function () {
 
  this.getAsyncData(function () {
 
    this.specialFunction();
 
    this.anotherSpecialFunction();
 
  }.bind(this));
 
}
ログイン後にコピー

ここで、これを環境に正常にバインドしました。

次は別の簡単な例です:

var foo = {
  x: 3
}
 
var bar = function(){
  console.log(this.x);
}
 
bar(); // undefined
 
var boundFunc = bar.bind(foo);
 
boundFunc(); // 3
ログイン後にコピー

次の例も一般的です:

this.x = 9;  // this refers to global "window" object here in the browser
var module = {
 x: 81,
 getX: function() { return this.x; }
};
 
module.getX(); // 81
 
var retrieveX = module.getX;
retrieveX(); 
// returns 9 - The function gets invoked at the global scope
 
// Create a new function with 'this' bound to module
// New programmers might confuse the
// global var x with module's property x
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
ログイン後にコピー

パート 4: ブラウザのサポート

ただし、このメソッドは IE8 以下ではサポートされていません。 MDN が提供するメソッドを使用して、IE の下位バージョンで .bind() メソッドをサポートさせることができます:

if (!Function.prototype.bind) {
 Function.prototype.bind = function (oThis) {
  if (typeof this !== "function") {
   // closest thing possible to the ECMAScript 5 internal IsCallable function
   throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  }
 
  var aArgs = Array.prototype.slice.call(arguments, 1),
    fToBind = this,
    fNOP = function () {},
    fBound = function () {
     return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                aArgs.concat(Array.prototype.slice.call(arguments)));
    };
 
  fNOP.prototype = this.prototype;
  fBound.prototype = new fNOP();
 
  return fBound;
 };
}
ログイン後にコピー

上記がこの記事の全内容であり、皆さんの学習に役立つことを願っています。 PHP 中国語 Web サイトをさらに学習していただければ幸いです。

JavaScript で Function.prototype.bind を理解する方法に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。

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