国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-21 00:18:09
字體:
供稿:網(wǎng)友
正好infinte同學(xué)提出“更優(yōu)雅的兼容”其實(shí)也和這個(gè)問題有一定的關(guān)聯(lián)(我們后面會(huì)看到)

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

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

還有“討厭”的第三個(gè)參數(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;
}
}),

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

foo = FunctionH.overload(function() {
return MSIE ? "IE": "NotIE";
},{
"IE": function() {...}
"NotIE": function() {...}
});
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 吉木乃县| 同心县| 沐川县| 开远市| 湘乡市| 新宾| 宣城市| 志丹县| 镇安县| 黄浦区| 新余市| 社旗县| 南郑县| 芦溪县| 尚志市| 苏尼特右旗| 巩义市| 磴口县| 靖宇县| 屯门区| 江安县| 象山县| 中卫市| 邯郸市| 射阳县| 都昌县| 扬州市| 乌拉特中旗| 武清区| 上林县| 城口县| 浏阳市| 稻城县| 新乐市| 九龙坡区| 武城县| 宝鸡市| 庆城县| 含山县| 惠州市| 越西县|