深入理解javascript之函數

來源:互聯網
上載者:User

標籤:

函數的範圍和this的指向我已經在前面的文章中講過,今天主要講講函數的綁定。函數綁定要建立一個函數,可以在特定的this環境中以指定參數調用另外一個函數。該技巧常常和回呼函數與事件處理常式一起使用,以便在將函數作為變數傳遞的同時保留函數的代碼執行環境。

函數綁定

看下面的例子:

var handler = {  message:"訊息來了!",  handlerClick :function(event){    document.write(this.message);  }}//一般的指定不能改變this的指向var btn = document.getElementById("btn");btn.addEventListener("click",handler.handlerClick,false);//返回undefined 因為this的範圍指向的是btn而不是hanlder

結果返回的是undefined,因為this的指向是btn這個DOM對象而不是hanlder,所以根本找不到handler.message。
所幸的是,我們可以通過一個閉包來解決這個問題。

//可以通過一個閉包來解決這個問題btn.addEventListener("click",function(event){  handler.handlerClick(event);},false);//返回 訊息來了!,解決問題

但是用閉包始終不是一個好辦法,因為過多的閉包會使代碼變得不易調試和理解,所以我們可以利用apply來調整this的指向。接下來我們定義一個bind方法。

//但是過多的使用閉包並不是一個好辦法,所以我們使用apply來改變this的指向function bind(fn,context){  return function(){    return fn.apply(context,arguments);  };}//通過自訂的bind方法來綁定事件btn.addEventListener("click",bind(handler.handlerClick,handler),false);

這樣就可以成功的將this的指向改變,這也是很多javascript第三方庫綁定函數的方法。值得一提的是,ES5中內建就有bind方法,這樣就不用我們再去自訂一個bind了:

//ES5中內建就有bind方法,就不需要我們自訂bind方法了。//使用內建的bind方法btn.addEventListener("click",handler.handlerClick.bind(handler),false);
函數柯裡化

什麼叫做函數柯裡化呢?其實就是function currying的翻譯。curry是咖喱的意思,呵呵。好了,迴歸正題,currying可以理解為就是用於建立已經設定好了一個或多個參數的函數。實現方法和函數綁定一樣,都是通過閉包來返回一個函數。兩者的區別在於,當函數被調用時,返回的函數還需要設定一些傳入的參數。

//再來說說函數柯裡化//概念:用於建立已經設定好了一個或多個參數的函數,可以理解為函數中套函數function add(num1,num2){  return num1+num2;}function curriedAdd(num3){  return add(5,num3);}document.write(add(2,3)+"<br>");//5document.write(curriedAdd(3));//8//上面的例子可以展示柯裡化的概念

上面的例子雖然不是柯裡化函數,但是可以展示其概念。下面我們介紹下建立函數柯裡化的通用方法:

//下面介紹建立函數柯裡化的通用方法function curry(fn){  var args = Array.prototype.slice.call(arguments,1);  return function(){    var innerArgs = Array.prototype.slice.call(arguments);    var finalArgs = args.concat(innerArgs);//將innerArgs拼接到args後    return fn.apply(null,finalArgs);  }}//使用方法如下:var curriedAdd = curry(add,5);document.write(curriedAdd(3)+"<br>");//8var curriedAddB = curry(add,5,10);document.write(curriedAddB()+"<br>");//15//可以看到參數靈活多變

也許看到這裡,還不能夠理解到底有什麼作用,那麼,我們可以將其和函數綁定結合起來,實現隨意數量的傳遞參數:

//這樣就可以在處理事件程式時傳遞其他參數了。//比如下例子:,注意我們傳入了name參數var handlerB = {  message:‘訊息來了!‘,  handlerClick : function(name,event){    document.write(this.message+":"+name);  }}btn.addEventListener("click",curriedBind(handlerB.handlerClick,handler,‘liufang‘),false);//訊息來了!:liufang

ES5中內建的bind方法同樣已實現了柯裡化,使用方法如下:

//ES5中的bind已經實現了柯裡化,所以可以直接使用:btn.addEventListener("click",handlerB.handlerClick.bind(handlerB,"liufangagain"),false);//訊息來了!:liufangagain

函數綁定和函數柯裡化提供了強大的動態函數功能,它們可以用於建立複雜的演算法和功能,但是會帶來額外的開銷。

本文全部執行個體地址: demo

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

深入理解javascript之函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.