亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ES6中javascript實現函數綁定及類的事件綁定功能的案例

發布時間:2021-04-13 11:39:42 來源:億速云 閱讀:187 作者:小新 欄目:web開發

這篇文章主要介紹ES6中javascript實現函數綁定及類的事件綁定功能的案例,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

具體如下:

函數綁定

箭頭函數可以綁定this對象,大大減少了顯式綁定this對象的寫法(call、apply、bind)。但是,箭頭函數并不適用于所有場合,所以 ES7 提出了 “ 函數綁定 ” ( function bind )運算符,用來取代call、apply、bind調用。雖然該語法還是 ES7 的一個提案,但是 Babel 轉碼器已經支持。

函數綁定運算符是并排的兩個雙冒號( :: ),雙冒號左邊是一個對象,右邊是一個函數。該運算符會自動將左邊的對象,作為上下文環境(即 this 對象),綁定到右邊的函數上面。

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("div.myClass")
::find("p")
::html("hahaha");

類中事件綁定

概述

ES6提供了類,給模塊化帶來了很大的幫助。在類里面綁定事件,一來是為了使得代碼結構清晰,二來是為了可以使用類的變量和方法。但是,由于事件的回調函數并不是由類的實例對象觸發,所以,事件回調函數里面并不能訪問類的this變量。另外,我們也不希望事件回調函數對外暴露,免得調用者直接調用。

簡單來說,我們就希望:

1. 事件回調函數要能訪問類的this變量
2. 事件回調函數不能直接調用

如何訪問類的this

方案一:將類的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解綁事件不需要提供回調函數,直接off就可以了。但是原生js需要提供回調函數也有它的道理,因為同一個元素的同一種事件可以綁定多個回調函數,所以你需要指出釋放哪一個。

方案二:使用bind()改變this的指向

有類A,在A中要添加mousemove事件,根據需求寫出下面代碼:

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

但是,這樣獲取不到類的this。onMouseMove的this將會指向document。因為事件是添加到document上的,所以自然是由document觸發事件并調用onMouseMove進行處理,所以onMouseMove中的this指向document。

比較正確的做法是:使用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 );

兩者的第二個參數并不相同。

正確的做法是: 將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")會產生一個唯一的值,這個值是在對象創建的時候才生成的,所以,調用者沒有辦法在寫代碼時知道這個值的,所以,就無法調用使用這個值命名的方法了,這樣就定義了一個私有方法。

以上是“ES6中javascript實現函數綁定及類的事件綁定功能的案例”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

达州市| 北票市| 江山市| 康定县| 金平| 正安县| 罗田县| 乌兰察布市| 新邵县| 密云县| 蓝山县| 类乌齐县| 本溪| 城市| 阿城市| 益阳市| 巫溪县| 蒙自县| 宝鸡市| 周至县| 施甸县| 遵义市| 布拖县| 彝良县| 龙山县| 石狮市| 景东| 黄龙县| 绥宁县| 望城县| 滨海县| 天水市| 潮安县| 广宗县| 兴宁市| 淳安县| 红河县| 如皋市| 天峨县| 桓仁| 内丘县|