最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript 通過模式匹配實(shí)現(xiàn)重載

 更新時間:2010年08月12日 10:19:12   作者:  
昨天rank同學(xué)向我提出一個問題,在實(shí)際應(yīng)用中有些接口需要提供類似于函數(shù)重載的功能,以方便開發(fā)者組織代碼邏輯,簡化使用者調(diào)用。
正好infinte同學(xué)提出“更優(yōu)雅的兼容”其實(shí)也和這個問題有一定的關(guān)聯(lián)(我們后面會看到)

在youa的腳本庫中Function的Helper中,添加支持重載的模式匹配
復(fù)制代碼 代碼如下:

/**
* 函數(shù)參數(shù)重載方法 overload,對函數(shù)參數(shù)進(jìn)行模式匹配。默認(rèn)的dispatcher支持*和...以及?,"*"表示一個任意類型的參數(shù),"..."表示多個任意類型的參數(shù),"?"一般用在",?..."表示0個或任意多個參數(shù)
* @method overload
* @static
* @optional {dispatcher} 用來匹配參數(shù)負(fù)責(zé)派發(fā)的函數(shù)
* @param {func_maps} 根據(jù)匹配接受調(diào)用的函數(shù)列表
* @return {function} 已重載化的函數(shù)
*/
overload: function(dispatcher, func_maps) {
if (! (dispatcher instanceof Function)) {
func_maps = dispatcher;
dispatcher = function(args) {
var ret = [];
return map(args, function(o) {return getType(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 包括兩個參數(shù),一個是負(fù)責(zé)處理匹配條件的dispatcher函數(shù)(可缺省),另一個是一組函數(shù)映射表,默認(rèn)dispatcher函數(shù)是根據(jù)實(shí)際調(diào)用的參數(shù)類型生成一個字符串,例如調(diào)用的三個參數(shù)依次為10、”a”、[1,2]將生成”number,string,array”,具體實(shí)現(xiàn)模式匹配的時候,將根據(jù)函數(shù)映射表的每一個”key”生成一個正則表達(dá)式,用這個正則表達(dá)式匹配dispatcher函數(shù)的返回值,如果匹配,則調(diào)用這個key對應(yīng)的處理函數(shù),否則依次匹配下一個key,例如:
復(fù)制代碼 代碼如下:

getEx: function(obj, prop, returnJson) {
var ret, propType = ObjectH.getType(prop);
if (propType == 'array') {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i++) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
} else {
//getEx(obj, props)
ret = [];
for (var i = 0; i & lt; prop.length; i++) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
} else {
//getEx(obj, prop)
var keys = (prop + "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i++) {
ret = ret[keys[i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
}
return ret;
},

上面這種情況下“萬惡”的 if 可以優(yōu)化為:
復(fù)制代碼 代碼如下:

getEx: FunctionH.overload({
"*,array,*": function(obj, prop, returnJson) {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i++) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
} else {
ret = [];
for (var i = 0; i & lt; prop.length; i++) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
return ret;
},
"*,string,*": function(obj, prop, returnJson) {
var keys = (prop + "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i++) {
ret = ret[keys[i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
return ret;
}
}),

OK,這種形式在一些人看來或許已經(jīng)比原來看起來好一些了,但是其實(shí)還可以更進(jìn)一步的——
復(fù)制代碼 代碼如下:

getEx: FunctionH.overload(function(args) {
return "prop is " + ObjectH.getType(args[1]);
},{
"prop is array": function(obj, prop, returnJson) {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i++) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
} else {
//getEx(obj, props)
ret = [];
for (var i = 0; i & lt; prop.length; i++) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
return ret;
},
"prop is string": function(obj, prop, returnJson) {
var keys = (prop + "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i++) {
ret = ret[keys[i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
return ret;
}
}),

還有“討厭”的第三個參數(shù),干脆也一并處理了——
復(fù)制代碼 代碼如下:

getEx: FunctionH.overload(function(args) {
return "prop is " + ObjectH.getType(args[1]) + " and returnJson is " +args[2];
},{
"prop is array and returnJson is true": function(obj, prop, returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i++) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
return ret;
},
"prop is array and returnJson is false": function(obj, prop, returnJson) {
ret = [];
for (var i = 0; i & lt; prop.length; i++) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
return ret;
},
"prop is string and returnJson is true": function(obj, prop, returnJson) {
var keys = (prop + "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i++) {
ret = ret[keys[i]];
}
var json = {};
json[prop] = ret;
return json;
},
"prop is string and returnJson is false": function(obj, prop, returnJson) {
var keys = (prop + "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i++) {
ret = ret[keys[i]];
}
return ret;
}
}),

例如說瀏覽器嗅探和特性探測之類種種,同理也能采用這個模式(當(dāng)然這種形式有利有弊,使用者自己權(quán)衡吧)——
復(fù)制代碼 代碼如下:

foo = FunctionH.overload(function() {
return MSIE ? "IE": "NotIE";
},{
"IE": function() {...}
"NotIE": function() {...}
});

相關(guān)文章

最新評論

剑河县| 且末县| 岑巩县| 锦屏县| 霍林郭勒市| 竹溪县| 柘城县| 武强县| 蒙山县| 柳河县| 上高县| 皋兰县| 图们市| 蒲江县| 磴口县| 明溪县| 大英县| 疏勒县| 肇源县| 普宁市| 富平县| 抚松县| 浦东新区| 苗栗市| 焦作市| 洪江市| 德格县| 临泽县| 昌都县| 旺苍县| 佛坪县| 隆回县| 修文县| 绍兴县| 故城县| 盐边县| 多伦县| 腾冲县| 祁东县| 张家口市| 陇川县|