今天繼續學習javascript系列教程,雖然是基礎,但我覺得還是有必要用心來學習的,不要怕難,不用怕忘記,不要怕學不會。哪個高手不是從零開始的,我要堅定自己的學習信心,並且認真的走下去。雖然路途艱辛,但總會在盡頭品嘗到芬芳的味道。
函數是定義一次但可以調用或執行任意多次的一段js代碼。函數有時會有參數,即函數被調用時指定了值的局部變量。函數常常使用這些參數來計算一個返回值,這個值也成為了函數調用表達式的值。
代碼如下function box(){
alert("年齡");
}
function box(name,age){
return name+age;
}
alert(box('caibaojian',24)); //www.111cn.net
tip:當函數遇到第一個return,就會終止函數往下執行。
三:argument對象
實際上,函數體內可以通過argument對象來接收傳遞進來的參數。
代碼如下
function box(){
return arguments[0] + '|'+arguments[1]; //得到每次參數的值
}
alert(box('caibaojian',24));
arguments對象的length屬性可以得到參數的數量。
function box(){
return arguments.length;
}
alert(box(1,2,3,4,5)); 5
javascript函數沒有重載功能
代碼如下function box(num,a){
return num+a;
}
function box(num){
return num;
}
alert(box(5,11)); 50 重載就是根據參數,選擇相同函數而參數不同的函數。
Javascript只認最後一個重名函數,根據順序。
但是javascript卻可以通過自身屬性去模擬函數重載。
書上常見的比較無意義的例子,比如一個計算器函數,如果參數為兩個數字,就執行加法運算。如果參數為三個數字,就執行乘法運算
這個函數大家最容易想到的實現就是
代碼如下
function calculate() {
if (arguments.length == 2) {
return arguments[0] + arguments[1];
}
if (arguments.length == 3) {
return arguments[0] * arguments[1] * arguments[2];
}
}
alert(calculate(1, 3))
這個函數看起來沒什麼不好,但隨著需求的增多,if分支就會越來越龐大,而且對應的模式也越來越難看。雖然if對於語言來說沒啥不好。但我們可以考慮使用另一個策略來實現這個需求。
這就是一個新的函數重載模式。代碼如下
代碼如下
var map = function (arr, callback, pThis) {
var len = arr.length;
var rlt = new Array(len);
for (var i = 0; i < len; i++) {
if (i in arr) rlt[i] = callback.call(pThis, arr[i], i, arr);
}
return rlt;
}
/**
* 函數參數重載方法 overload,對函數參數進行模式匹配。默認的dispatcher支持*和...以及?,"*"表示一個任意類型的參數,"..."表示多個任意類型的參數,"?"一般用在",?..."表示0個或任意多個參數
* @method overload
* @static
* @optional {dispatcher} 用來匹配參數負責派發的函數
* @param {func_maps} 根據匹配接受調用的函數列表
* @return {function} 已重載化的函數
*/
var FunctionH = {
overload: function (dispatcher, func_maps) {
if (!(dispatcher instanceof Function)) {
func_maps = dispatcher;
dispatcher = function (args) {
var ret = [];
return map(args, function (o) { return typeof o}).join();
}
}
return function () {
var key = dispatcher([].slice.apply(arguments));
for (var i in func_maps) {
var pattern = new RegExp("^" + i.replace("*", "[^,]*").replace("...", ".*") + "$");
if (pattern.test(key)) {
return func_maps[i].apply(this, arguments);
}
}
}
}
};
FunctionH.overload 包括兩個參數,一個是負責處理匹配條件的dispatcher函數(可缺省),另一個是一組函數映射表,默認dispatcher函數是根據實際調用的參數類型生成一個字符串,例如調用的三個參數依次為10、”a”、[1,2]將生成”number,string,array”,具體實現模式匹配的時候,將根據函數映射表的每一個”key”生成一個正則表達式,用這個正則表達式匹配dispatcher函數的返回值,如果匹配,則調用這個key對應的處理函數,否則依次匹配下一個key。這樣剛才那個計算機函數的需求就可以寫成為
代碼如下
var Calculate = FunctionH.overload({
'number,number': function () {
return arguments[0] + arguments[1];
},
'number,number,number': function () {
return arguments[0] * arguments[1] * arguments[2];
}
});
alert(Calculate(1,2,3));
順便對於浏覽器兼容的代碼也可以寫成下面類似的形式
代碼如下
var MSIE = navigator.userAgent.indexOf('MSIE') !== -1;
var foo = FunctionH.overload(function () {
return MSIE ? "IE" : "NotIE";
}, {
"IE": function () {
alert('this is ie');
},
"NotIE": function () {
alert('notie');
}
});
foo();