這篇文章主要介紹了JS中使用apply方法通過不同數(shù)量的參數(shù)調(diào)用函數(shù)的方法的相關(guān)資料,需要的朋友可以參考下
apply()方法定義
函數(shù)的apply()方法和call方法作用相同,區(qū)別在于接收的參數(shù)的方式不同。
apply()方法接收兩個參數(shù),一個是對象,一個是參數(shù)數(shù)組。
apply()作用
1、用于延長函數(shù)的作用域
示例:
var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"
這里通過apply()方法把函數(shù)動態(tài)綁定到了對象o上了,這時this指向o對象,得到結(jié)果"blue"。
2、對象不需要與方法有任何耦合關(guān)系
下面舉個耦合的例子,看如何通過apply來解決這種耦合。
var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
o.sayColor=sayColor;
o.sayColor();//"blue"
這里先將函數(shù)放到了對象o中,這里對象和方法就緊耦合到一起了,方法的調(diào)用必須通過對象o。
沒有使用apply()和call()方法那樣靈活。
重構(gòu)上面代碼,得到前例中的代碼。
var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"
這里對象并沒有綁定任何方法,只是在需要使用的時候,利用函數(shù)的apply或call方法來動態(tài)綁定。
對象和方法之間沒有耦合在一起。這里還可以通過ES5提供的bind()方法來完成
3、實現(xiàn)可變參數(shù)函數(shù)傳參
下面一個計算任意數(shù)量數(shù)字平均值的函數(shù)
average(,,);
average();
average(,,,,,,,,);
average(,,,,,,,,,);
average函數(shù)是一個稱為可變參數(shù)或可變元函數(shù)(函數(shù)的元數(shù)是指其期望的參數(shù)個數(shù))的例子。
當(dāng)然這個函數(shù)也可以寫成一個接收數(shù)組的形式。
averageOfArray([,,]);
averageOfArray([]);
averageOfArray([,,,,,,,,]);
averageOfArray([,,,,,,,,,]);
使用可變參數(shù)的函數(shù)更簡潔、優(yōu)雅??勺儏?shù)函數(shù)具有便捷的語法,至少讓調(diào)用者預(yù)先明確地知道提供了多少個參數(shù)。
如果我有這樣一個數(shù)組
var scores=getAllScores();
如何使用average函數(shù)計算平均值呢?
1.可變參數(shù)函數(shù)版本。
這時就可以和apply()方法配合使用,這里因為函數(shù)并沒用引用this變量,因此第一個參數(shù)我們傳入一個null。代碼如下:
var scores=getAllScores();
average.apply(null,scores);
2.直接參數(shù)為數(shù)組的形式
這里可以直接傳入數(shù)組參數(shù)。
var scores=getAllScores();
averageOfArray(scores);
以上兩種形式,個人覺得都是可以,反而第二種更簡單。多知道一種方法,對于遇到別人寫的函數(shù)時,可以輕松應(yīng)對,不需要重構(gòu)代碼。這個好處反而更多。
4、實現(xiàn)可變參數(shù)方法的傳值
示例:buffer對象包含一個可變參數(shù)的append方法,該方法添加元素到函數(shù)內(nèi)部的state數(shù)組中。
var buffer={
state:[],
append:function(){
for(var i=,n=arguments.length;i<n;i++){
this.state.push(arguments[i]);
}
}
};
這時append方法可以接受任意多個參數(shù)。
buffer.append('Hello,');
buffer.append('firtName',' ','lastName','!');
buffer.append('newLine');
形式如
buffer.append(arg1,arg2,arg3,...)
借助apply方法的this參數(shù),我們可以指定一個可計算的數(shù)組調(diào)用append方法
buffer.append.apply(buffer,getInputStrings());
注意:這里的buffer很重要,如果傳遞不同的對象,則append方法將嘗試修改該錯誤對象的state屬性。
提示
•使用apply方法指定一個可計算的參數(shù)數(shù)組來調(diào)用可變參數(shù)的函數(shù)
•使用apply方法的第一個參數(shù)給可變參數(shù)的方法提供一個接收者
附錄一
average函數(shù)
function average(){
var args=[].slice.call(arguments);
var sum=args.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/args.length,);
}
averageOfArray函數(shù)
function averageOfArray(arr){
var sum=arr.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/arr.length,);
}
ES5 bind()方法
這個方法創(chuàng)建一個函數(shù)的實例,其this值會被綁定到傳給bind()函數(shù)的值。
例如
var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
var oSayColor=sayColor.bind(o);
oSayColor();//"blue"
兼容低版本,參考使用下面的版本 :
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = [].slice.call(arguments, ),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP? this: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
};
}