手机
当前位置:查字典教程网 >编程开发 >Javascript教程 >JavaScript 通过模式匹配实现重载
JavaScript 通过模式匹配实现重载
摘要:正好infinte同学提出“更优雅的兼容”其实也和这个问题有一定的关联(我们后面会看到)在youa的脚本库中Function的Helper中...

正好infinte同学提出“更优雅的兼容”其实也和这个问题有一定的关联(我们后面会看到)

在youa的脚本库中Function的Helper中,添加支持重载的模式匹配

复制代码 代码如下:

/**

* 函数参数重载方法 overload,对函数参数进行模式匹配。默认的dispatcher支持*和...以及?,"*"表示一个任意类型的参数,"..."表示多个任意类型的参数,"?"一般用在",?..."表示0个或任意多个参数

* @method overload

* @static

* @optional {dispatcher} 用来匹配参数负责派发的函数

* @param {func_maps} 根据匹配接受调用的函数列表

* @return {function} 已重载化的函数

*/

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 包括两个参数,一个是负责处理匹配条件的dispatcher函数(可缺省),另一个是一组函数映射表,默认dispatcher函数是根据实际调用的参数类型生成一个字符串,例如调用的三个参数依次为10、”a”、[1,2]将生成”number,string,array”,具体实现模式匹配的时候,将根据函数映射表的每一个”key”生成一个正则表达式,用这个正则表达式匹配dispatcher函数的返回值,如果匹配,则调用这个key对应的处理函数,否则依次匹配下一个key,例如:

复制代码 代码如下:

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 可以优化为:

复制代码 代码如下:

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,这种形式在一些人看来或许已经比原来看起来好一些了,但是其实还可以更进一步的——

复制代码 代码如下:

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;

}

}),

还有“讨厌”的第三个参数,干脆也一并处理了——

复制代码 代码如下:

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;

}

}),

例如说浏览器嗅探和特性探测之类种种,同理也能采用这个模式(当然这种形式有利有弊,使用者自己权衡吧)——

复制代码 代码如下:

foo = FunctionH.overload(function() {

return MSIE ? "IE": "NotIE";

},{

"IE": function() {...}

"NotIE": function() {...}

});

【JavaScript 通过模式匹配实现重载】相关文章:

javascript实现行拖动的方法

Javascript节点关系实例分析

用JavaScript实现对话框的教程

JavaScript实现表格点击排序的方法

JavaScript Base64编码和解码,实现URL参数传递。

JavaScript中的this,call,apply使用及区别详解

JavaScript实现简单的数字倒计时

javascript组合使用构造函数模式和原型模式实例

JavaScript的9种继承实现方式归纳

JavaScript的while循环的使用

精品推荐
分类导航