javascript中如何將帶參數函數包裝成無參數函數

在編寫javascript腳本時,可能需要將一個原本具有輸入參數的函數包裝成一個無輸入參數的函數,這通常是爲了將其綁定到某個事件函數上,事件函數是要求無輸入參數的,例如下面的代碼,就是爲一個div綁定了onclick事件:

var div = document.createElement("div");
div.onclick 
= div_onclick; //爲事件綁定事件函數

function div_onclick()
{
    alert(
"div onclick event");
}

 可以注意到,這裏的div_onclick()函數是沒有輸入參數的,因此,可以使用div.οnclick=div_onclick來爲div綁定點擊時觸發的事件函數,但是,如果div_onclick是個帶有輸入參數的函數,那麼,該如何綁定事件函數呢?

function div_onclick(str)
{
    alert(str);
}

如上面所示的函數,div_onclick已經帶有了一個str參數,如何來爲上面的那個div的點擊事件綁定這個帶輸入參數的函數呢,大多數剛剛接觸javascript的人容易犯的錯誤就是寫出下面的代碼,這樣的代碼是不會得到想要的效果的:

var str = "div onclick event";
var div = document.createElement("div");
div.onclick 
= div_onclick(str); //<----------------錯誤的代碼

function div_onclick(str)
{
    alert(str);
}

其中錯誤的那行代碼的真實運行情況應該是:先以str作爲參數調用div_onclick函數,顯然,調用的結果就是彈出了alert窗口,點擊確定後,div_onclick函數將返回,返回值再給div.onclick賦值,這和我們打算將函數div_onclick綁定到div.onclick上的初衷是不符合的。

這就存在了一個問題,我們既要爲div.onclick綁定一個函數,又要能夠爲綁定的函數傳遞一些參數,顯然,我們需要能夠將帶參數的函數以及我們想要傳遞給它的參數一起包裝成一個無參數的新函數,再將這個無參數的新函數綁定到相應的事件上面去,實現的方法有好多種,這裏介紹一種比較簡單通用的方法,這種方法可以將任意一個帶參數的函數包裝爲一個不帶參數的函數,該方法要求添加如下函數定義:

Function.prototype.bind   =   function()   
{   
      
var   __method   =   this;   
      
var   arg   =   arguments;   
      
return   function()   {   
          __method.apply(window,   arg);   
      }
   
  }

關於這個函數的實現就不再多解釋了,這裏只說明一點,這個代碼段是爲所有的函數定義了一個函數名爲bind的公共靜態函數,由於javascript的面向對象的特性,使得任何一個以function來定義的函數本身都是一個Function類,關於上面的函數定義方式,請參閱《Javascript——Prototype Based Language》。

將上面的函數加入到你的文件中,就可以使用它來將帶參數的函數包裝成一個無參數函數了。在div的例子中,我們將得到如下的代碼:

Function.prototype.bind   =   function()  
 
...{   
      
var   __method   =   this;   
      
var   arg   =   arguments;   
      
return   function()   ...{   
          __method.apply(window,   arg);   
      }
   
  }


var str = "div onclick event";
var div = document.createElement("div");
div.onclick 
= div_onclick.bind(str); //將帶參數的函數包裝成無參數的函數

function div_onclick(str)
{
    alert(str);
}

這樣,就能實現我們的初衷了。更復雜的,參數可以是多個,也可以是任意類型的。這裏我給出兩個例子,以說明這種應用。

示例一:動態爲表格增加行,併爲行綁定帶參數的事件函數,代碼如下:

<html>
<script language=javascript>
function test()
{
    
for(var i=0;i<10;i++)
   
{
        
var tr = document.all.tb.insertRow();
        
var td = tr.insertCell();
        td.innerHTML 
= "這是第"+i+"";
        tr.onclick 
= myfunc.bind(i,td);    
    }

}


function myfunc(str,td)
{
    alert(str
+":"+td.innerHTML);
}


Function.prototype.bind 
= function()
{   
      
var   __method   =   this;   
      
var   arg   =   arguments;   
      
return   function()   {   
          __method.apply(window,   arg);   
      }
   
}
   
</script>
<body>
<input type=button value=test onclick=test()><br>
<table id=tb width=200 border=1>
<tr><td bgcolor=yellow>這裏是表頭部分</td></tr>
</table>
</body>
</html>

 

示例二:爲定時器綁定帶參數的函數,代碼如下:

<html>
<script language=javascript>
function init()
{
    
var param = "hello world";
    timername 
= setInterval(sayHello.bind(param),1000);
}


function sayHello(str)
{
    document.body.innerHTML 
+= str + "<br>";
}


Function.prototype.bind 
= function()
{   
      
var   __method   =   this;   
      
var   arg   =   arguments;   
      
return   function()   {   
          __method.apply(window,   arg);   
      }
   
}
   
</script>
<body onload=init()>

</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章