国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

ES6中javascript實(shí)現(xiàn)函數(shù)綁定及類的事件綁定功能詳解

2024-05-06 16:40:47
字體:
供稿:網(wǎng)友

本文實(shí)例講述了javascript/264530.html">ES6中javascript實(shí)現(xiàn)函數(shù)綁定及類的事件綁定功能的方法。分享給大家供大家參考,具體如下:

函數(shù)綁定

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

函數(shù)綁定運(yùn)算符是并排的兩個(gè)雙冒號(hào)( :: ),雙冒號(hào)左邊是一個(gè)對(duì)象,右邊是一個(gè)函數(shù)。該運(yùn)算符會(huì)自動(dòng)將左邊的對(duì)象,作為上下文環(huán)境(即 this 對(duì)象),綁定到右邊的函數(shù)上面。

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);}

如果雙冒號(hào)左邊為空,右邊是一個(gè)對(duì)象的方法,則等于將該方法綁定在該對(duì)象上面。

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

由于雙冒號(hào)運(yùn)算符返回的還是原對(duì)象,因此可以采用鏈?zhǔn)綄懛ā?/p>

// 例一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提供了類,給模塊化帶來了很大的幫助。在類里面綁定事件,一來是為了使得代碼結(jié)構(gòu)清晰,二來是為了可以使用類的變量和方法。但是,由于事件的回調(diào)函數(shù)并不是由類的實(shí)例對(duì)象觸發(fā),所以,事件回調(diào)函數(shù)里面并不能訪問類的this變量。另外,我們也不希望事件回調(diào)函數(shù)對(duì)外暴露,免得調(diào)用者直接調(diào)用。

簡單來說,我們就希望:

1. 事件回調(diào)函數(shù)要能訪問類的this變量
2. 事件回調(diào)函數(shù)不能直接調(diào)用

如何訪問類的this

方案一:將類的this保存成一個(gè)局部變量

this的指代是動(dòng)態(tài)改變的,但是局部變量的指代卻是明確的,并且,函數(shù)定義的局部變量在整個(gè)函數(shù)里面都可以用。所以,我們可以使用let that = this保存類的this變量。

class A{  //綁定事件的方法  bindEvent(){   let that = this;   this.button1.on('click',function(e){      this.addClass('on'); //this指代所點(diǎn)的元素      that.doSomething(); //that指向類的this   })  }  doSomething(){   //事件處理函數(shù)  }  //解綁事件  unBindEvent(){   this.button1.off();  }}

這種方法只在使用jquery時(shí)有用,因?yàn)閖query解綁事件不需要提供回調(diào)函數(shù),直接off就可以了。但是原生js需要提供回調(diào)函數(shù)也有它的道理,因?yàn)橥粋€(gè)元素的同一種事件可以綁定多個(gè)回調(diào)函數(shù),所以你需要指出釋放哪一個(gè)。

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

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

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

但是,這樣獲取不到類的this。onMouseMove的this將會(huì)指向document。因?yàn)槭录翘砑拥絛ocument上的,所以自然是由document觸發(fā)事件并調(diào)用onMouseMove進(jìn)行處理,所以onMouseMove中的this指向document。

比較正確的做法是:使用bind()函數(shù)改變onMouseMove中this的指向,同時(shí)將事件回調(diào)函數(shù)移到類外面

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

但是這樣仍然存在問題,事件移除不掉了!因?yàn)?code>this.bind()每次調(diào)用都會(huì)返回一個(gè)新的函數(shù),所以:

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

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

兩者的第二個(gè)參數(shù)并不相同。

正確的做法是:bind()的結(jié)果保存到一個(gè)變量中:

class A{  constructor(){    this._onMouseMove = onMouseMove.bind(this);  //看這里  }  //添加事件  addEvent(){    document.addEventListener( 'mousemove', this._onMouseMove , false );  }  //添加事件  removeEvent(){    document.removeEventListener( 'mousemove', this._onMouseMove , false );  }}//事件回調(diào)函數(shù)中function onMouseMove(event){  console.log(this);}

如何定義私有的事件回調(diào)函數(shù)

在Java中,不想對(duì)外暴露的方法可以定義為私有方法,但是ES6并沒有提供私有方法,只能通過一些辦法模擬。但是,事件回調(diào)函數(shù)比較特別,因?yàn)槭录硕x,還要移除,這會(huì)帶來額外的麻煩。但還是有辦法的:

使用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 );  }}//事件回調(diào)函數(shù)中function onMouseMove(event){  console.log(this);}

Symbol("_onMouseMove")會(huì)產(chǎn)生一個(gè)唯一的值,這個(gè)值是在對(duì)象創(chuàng)建的時(shí)候才生成的,所以,調(diào)用者沒有辦法在寫代碼時(shí)知道這個(gè)值的,所以,就無法調(diào)用使用這個(gè)值命名的方法了,這樣就定義了一個(gè)私有方法。

希望本文所述對(duì)大家基于ECMAScript的程序設(shè)計(jì)有所幫助。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 甘德县| 卢氏县| 万盛区| 南投市| 胶南市| 石家庄市| 岢岚县| 北流市| 湟中县| 广宁县| 玉溪市| 察雅县| 眉山市| 子长县| 香港 | 兴山县| 合川市| 商水县| 高密市| 广灵县| 肃宁县| 贵阳市| 苏州市| 连州市| 陇南市| 武宣县| 宜州市| 蓝田县| 丰台区| 汕尾市| 平潭县| 彭州市| 沙坪坝区| 革吉县| 潜山县| 洛隆县| 清河县| 浦北县| 汽车| 抚州市| 伊通|