1. JavaScripth函式不能夠實作多載
什么是多載
多載,簡單說,就是函式或者方法有相同的名稱,但是引數串列不相同的情形,這樣的同名不同引數的函式或者方法之間,互相稱之為多載函式或者方法,參考javascript 高級程式設計(第三版)P66
ES函式不能夠像傳統意義上那樣實作多載,而在其他語言中(如java)中,可以為一個函式撰寫兩個定義,只要這兩個定義的簽名(接受的引數的型別和數量)不同即可,
如果在javascript 中定義了兩個名字相同的函式,則名字屬于后定義的函式,
function addSomeNumber (num) {
return num + 100;
}
function addSomeNumber (num){
return num + 200;
}
var result = addSomeNumber(100);//300
2. 怎么實作(模仿)函式的多載
在Javascript 高級程式設計(第三版)中提到,通過檢查函式中引數的型別和數量并作出不同的反應,可以模仿方法的多載,
function doAdd (){
if(arguments.length === 1){
alert(arguments[0] + 10);
}else if (arguments.length === 2){
alert(arguments[0] + arguments[1]);
}
}
doAdd(10);//20
doAdd(10,20);//30
3. 一個巧妙的辦法實作多載
在JQuery之父John Resig寫的《secrets of the JavaScript ninja》找到了一個絕佳巧妙的方法!那種方法充分的利用了閉包的特性!
在介紹這個方法之前,我們先來看看外國人名字組成哈,比如,John Resig,John是first-name,Resig是last-name,就相當于我們的姓名由姓和名組成一樣,
我們現在有這樣的一個需求,有一個people物件,里面存著一些人名,如下:
var people = {
values: ["Dean Edwards", "Sam Stephenson", "Alex Russell", "Dean Tom"]
};
我們希望people物件擁有一個find方法,當不傳任何引數時,就會把people.values里面的所有元素回傳來;當傳一個引數時,就把first-name跟這個引數匹配的元素回傳來;當傳兩個引數時,則把first-name和last-name都匹配的才回傳來,因為find方法是根據引數的個數不同而執行不同的操作的,所以,我們希望有一個addMethod方法,能夠如下的為people添加find的多載:
addMethod(people, "find", function() {}); /*不傳參*/
addMethod(people, "find", function(a) {}); /*傳一個*/
addMethod(people, "find", function(a, b) {}); /*傳兩個*/
這時候問題來了,這個全域的addMethod方法該怎么實作呢?John Resig的實作方法如下,代碼不長,但是非常的巧妙:
function addMethod(object, name, fn) {
var old = object[name]; //把前一次添加的方法存在一個臨時變數old里面
object[name] = function() { // 重寫了object[name]的方法
//如果呼叫object[name]方法時,傳入的引數個數跟預期的一致,則直接呼叫
if(fn.length === arguments.length) {
return fn.apply(this, arguments);
// 否則,判斷old是否是函式,如果是,就呼叫old
} else if(typeof old === "function") {
return old.apply(this, arguments);
}
}
}
現在,我們一起來分析一個這個addMethod函式,它接收3個引數,第一個為要系結方法的物件,第二個為系結的方法名稱,第三個為需要系結的方法(一個匿名函式),函式體的的分析已經在注釋里面了,
OK,現在這個addMethod方法已經實作了,我們接下來就實作people.find的多載啦!全部代碼如下:
//addMethod
function addMethod(object, name, fn) {
var old = object[name];
object[name] = function() {
if(fn.length === arguments.length) {
return fn.apply(this, arguments);
} else if(typeof old === "function") {
return old.apply(this, arguments);
}
}
}
var people = {
values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};
/* 下面開始通過addMethod來實作對people.find方法的多載 */
// 不傳引數時,回傳peopld.values里面的所有元素
addMethod(people, "find", function() {
return this.values;
});
// 傳一個引數時,按first-name的匹配進行回傳
addMethod(people, "find", function(firstName) {
var ret = [];
for(var i = 0; i < this.values.length; i++) {
if(this.values[i].indexOf(firstName) === 0) {
ret.push(this.values[i]);
}
}
return ret;
});
// 傳兩個引數時,回傳first-name和last-name都匹配的元素
addMethod(people, "find", function(firstName, lastName) {
var ret = [];
for(var i = 0; i < this.values.length; i++) {
if(this.values[i] === (firstName + " " + lastName)) {
ret.push(this.values[i]);
}
}
return ret;
});
// 測驗:
console.log(people.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(people.find("Dean Edwards")); //["Dean Edwards"]
原文鏈接:https://blog.csdn.net/ycq521131/java/article/details/80600298
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/96622.html
標籤:JavaScript
上一篇:堆疊
