ホームページ  >  記事  >  ウェブフロントエンド  >  ES6のJavaScriptの関数バインディング関数とクラスイベントバインディング関数の詳細説明

ES6のJavaScriptの関数バインディング関数とクラスイベントバインディング関数の詳細説明

小云云
小云云オリジナル
2017-12-23 10:29:441936ブラウズ

この記事では、ES6 における関数バインディングとクラスイベントバインディング関数の JavaScript 実装を中心に、ES6 での関数バインディングとクラスイベントバインディングの原理、実装方法、関連する操作スキル、注意点をサンプル形式で分析します。友人も参考にしていただけると思いますので、皆さんのお役に立てれば幸いです。

関数バインド

アロー関数はこのオブジェクトをバインドできるため、このオブジェクトを明示的にバインドする方法 (呼び出し、適用、バインド) の数が大幅に減ります。ただし、アロー関数はすべての状況に適しているわけではないため、ES7 では、call、apply、bind 呼び出しを置き換える「関数バインド」演算子を提案しています。この構文はまだ ES7 の提案ですが、Babel トランスコーダはすでにそれをサポートしています。

関数バインディング演算子は、2 つの二重コロン (::) が並んでいます。二重コロンの左側はオブジェクトで、右側は関数です。この演算子は、左側のオブジェクトをコンテキスト (つまり、このオブジェクト) として右側の関数に自動的にバインドします。

foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return obj::hasOwnProperty(key);
}

二重コロンの左側が空で、右側がオブジェクトのメソッドの場合、メソッドをオブジェクトにバインドすることと同じです。

var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;
let log = ::console.log;
// 等同于
var log = console.log.bind(console);

二重コロン演算子は依然として元のオブジェクトを返すため、チェーン書き込みを使用できます。

// 例一
import { map, takeWhile, forEach } from "iterlib";
getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));
// 例二
let { find, html } = jake;
document.querySelectorAll("p.myClass")
::find("p")
::html("hahaha");

クラス内のイベント バインディング

概要

ES6 は、モジュール化に大きな助けとなるクラスを提供します。クラス内でイベントをバインドすることは、第一にコード構造を明確にすることであり、第二に、クラスの変数とメソッドを使用できるようにすることです。ただし、イベント コールバック関数はクラスのインスタンス オブジェクトによってトリガーされないため、イベント コールバック関数内でクラスの this 変数にアクセスすることはできません。さらに、呼び出し元がイベント コールバック関数を直接呼び出すことができないように、イベント コールバック関数を外部に公開したくありません。

簡単に言うと、次のことを望んでいます

1. イベント コールバック関数はクラスの this 変数にアクセスできる必要があります
2. イベント コールバック関数は直接呼び出すことはできません

クラスの this にアクセスする方法

オプション1:クラスのthisを保存する ローカル変数になります

thisの参照は動的に変化しますが、ローカル変数の参照は明確であり、関数で定義したローカル変数は関数全体で使用できます。したがって、 let that = this を使用して、クラスの this 変数を保存できます。

class A{
  //绑定事件的方法
  bindEvent(){
   let that = this;
   this.button1.on('click',function(e){
      this.addClass('on'); //this指代所点的元素
      that.doSomething(); //that指向类的this
   })
  }
  doSomething(){
   //事件处理函数
  }
  //解绑事件
  unBindEvent(){
   this.button1.off();
  }
}

このメソッドは、jquery を使用する場合にのみ役立ちます。jquery のバインド解除イベントはコールバック関数を提供する必要がなく、直接オフにするだけだからです。しかし、ネイティブ JS がコールバック関数を提供する必要があるのには理由があります。同じ要素の同じイベントが複数のコールバック関数にバインドされる可能性があるため、どれを解放するかを指定する必要があるからです。

オプション 2: このポイントを変更するには、bind() を使用します。

クラス A があります。A には、要件に従って、mousemove イベントを追加する必要があります。

class A{
  //添加事件
  addEvent(){
    document.addEventListener( 'mousemove', onMouseMove, false );
  }
  //添加事件
  removeEvent(){
    document.removeEventListener( 'mousemove', onMouseMove , false );
  }
}
//事件回调函数中
function onMouseMove(event){
  console.log(this);  //#document
}

ただし、取得することはできません。このようにクラスのこれを。 onMouseMoveのこれはドキュメントを指します。イベントがドキュメントに追加されるため、イベントはドキュメントによって自然にトリガーされ、処理のために onMouseMove が呼び出されるため、onMouseMove の this はドキュメントを指します。

より正しいアプローチは、bind() 関数を使用して onMouseMove の this のポインタを変更し、同時にイベント コールバック関数をクラスの外に移動することです:

class A{
  //添加事件
  addEvent(){
    document.addEventListener( 'mousemove', onMouseMove.bind(this), false );
  }
  //添加事件
  removeEvent(){
    document.removeEventListener( 'mousemove', onMouseMove.bind(this) , false );
  }
}
//事件回调函数中
function onMouseMove(event){
  console.log(this);
}

しかし、まだ問題があり、イベントは実行できません除去される! this.bind() は呼び出されるたびに新しい関数を返すため、

document.addEventListener( 'mousemove', onMouseMove.bind(this), false );

document.removeEventListener( 'mousemove', onMouseMove.bind(this), false );

の 2 番目のパラメーターは同じではありません。

正しいアプローチは次のとおりです:bind() の結果を変数に保存します:

class A{
  constructor(){
    this._onMouseMove = onMouseMove.bind(this);  //看这里
  }
  //添加事件
  addEvent(){
    document.addEventListener( 'mousemove', this._onMouseMove , false );
  }
  //添加事件
  removeEvent(){
    document.removeEventListener( 'mousemove', this._onMouseMove , false );
  }
}
//事件回调函数中
function onMouseMove(event){
  console.log(this);
}

プライベート イベント コールバック関数を定義する方法

Java では、外部に公開したくないメソッドは次のように定義できます。プライベート メソッドですが、ES6 では一部のメソッドを通じてのみシミュレートできるプライベート メソッドが提供されません。ただし、イベント コールバック関数は特殊であり、イベントを定義するだけでなく削除する必要があるため、追加の問題が発生します。しかし、まだ方法はあります:

Symbol 変数を使用して定義します

const _onMouseMove = Symbol("_onMouseMove");
class A{
  constructor(){
    this[_onMouseMove] = onMouseMove.bind(this);
  }
  //添加事件
  addEvent(){
    document.addEventListener( 'mousemove', this[_onMouseMove] , false );
  }
  //添加事件
  removeEvent(){
    document.removeEventListener( 'mousemove', this[_onMouseMove] , false );
  }
}
//事件回调函数中
function onMouseMove(event){
  console.log(this);
}

Symbol("_onMouseMove") は一意の値を生成します。この値はオブジェクトの作成時に生成されるため、呼び出し元はコードを記述することができません。値はその時点で既知であるため、この値を使用して名前を付けられたメソッドを呼び出すことはできず、プライベート メソッドが定義されます。

関連する推奨事項:

JavaScript 関数バインディングの使用法を例とともに説明

JavaScript インタラクションに関数バインディング コードを使用する方法の詳細な説明

JavaScript 関数バインディング

以上がES6のJavaScriptの関数バインディング関数とクラスイベントバインディング関数の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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