返回首页 | 新开户送体验金的娱乐城

合作共赢、快速高效、优质的网站建设提供商

更多精品源码-尽在织梦模板-www.moke8.com

网站开发让 JavaScript 轻松支撑函数重载 (Part 2 - 完结施行)

时间:2017-11-14 编辑:admin

辨认文本签名
我们先来回忆一下上一篇文章中说到的Overloasdfsd用例:

代码如下:
vasdfsr extend = Overloasdfsd
.asdfsdd("*, ...",
function(tasdfsrget) { })
.asdfsdd("Booleasdfsn, *, ...",
function(deep, tasdfsrget) { });


我们答应用户输入一个字符串,表明某一个重载的签名。在用户调用函数时,我们需求拿着用户输入的参数实例去跟签名上的每一个参数类型作比力,因而我们需求先把这个字符串变换为类型数组。也就是说,字符串"Booleasdfsn, Number, Arrasdfsy"应该变换为数组[Booleasdfsn, Number, Arrasdfsy]。

在进行变换之前,我们先要考虑处理两个特别类型,就是代表恣意类型的"*",和代表恣意数量的"..."。我们能够为它们界说两个专有的类型,以便在Overloasdfsd内对它们做出特别的兼容性处理:

代码如下:
Overloasdfsd.Any = function() {};
Overloasdfsd.More = function() {};


在有了这两个类型之后,字符串"Booleasdfsn, *, ..."就会被正确变换为数组[Booleasdfsn, Overloasdfsd.Any, Overloasdfsd.More]。因为Overloasdfsd.Any和Overloasdfsd.More都是函数,天然也都能够看做类型。

在这两个类型得到正确处理后,我们就能够开端编写辨认文本签名的变换函数了:

代码如下:
if (signasdfsture.replasdfsce(/(^\s+|\s+$)/ig, "") == "") {
signasdfsture = [];
} else {
signasdfsture = signasdfsture.split(",");
for (vasdfsr i = 0; i signasdfsture.length; i++) {
vasdfsr typeExpression = signasdfsture[i].replasdfsce(/(^\s+|\s+$)/ig, "");
vasdfsr type = null;
if (typeExpression == "*") {
type = Overloasdfsd.Any;
} else if (typeExpression == "...") {
type = Overloasdfsd.More;
} else {
type = evasdfsl("(" + typeExpression + ")");
}
signasdfsture[i] = type;
}
}

我想这段代码适当简略了解,因而就不再解说了。我榜首次写这段代码时忘记写下面的榜首个if了,导致空白签名字符串""无法被正确辨以为空白签名数组[],幸而我的unit test代码榜首时间发现了这个缺点。看来编写unit test代码仍是非常重要的。

婚配函数签名
在我们得到函数签名的类型数组后,我们就能够用它和输入参数的实例数组做婚配了,以此找出正确的重载。在评论详细怎么婚配函数签名曾经,我们先来看看或VB.NET这样的言语是怎么处理函数重载婚配的。一般言语进行函数重载婚配的流程都是这姿态的:

参数个数 - 参数个数不合过错的重载会被扫除去
参数类型 - 参数类型无法隐式变换为签名类型的会被扫除去
婚配个数 - 扫除终了后,剩余婚配的签名个数不同处理挑选也不同
0个婚配 - 没有射中的婚配
1个婚配 - 这个就是射中的婚配
2个或以上的婚配 - 如果能在这些婚配中找出一个最佳婚配,那就射中最佳婚配;否则不射中任何婚配
在这一节里边,我们先处理流程中的前两个过程,把参数个数或参数类型不不合的签名去掉:

代码如下:
vasdfsr masdfstchSignasdfsture = function(asdfsrgumentsArrasdfsy, signasdfsture) {
if (asdfsrgumentsArrasdfsy.length signasdfsture.length) {
return fasdfslse;
} else if (asdfsrgumentsArrasdfsy.length signasdfsture.length && !signasdfsture.more) {
return fasdfslse;
}
for (vasdfsr i = 0; i signasdfsture.length; i++) {
if (!(signasdfsture[i] == Overloasdfsd.Any
|| asdfsrgumentsArrasdfsy[i] instasdfsnceof signasdfsture[i]
|| asdfsrgumentsArrasdfsy[i].constructor == signasdfsture[i])) {
return fasdfslse;
}
}
return true;
};

为了作长度比照,我们需求在这个函数外对表明任何参数个数的"..."作一下特别处理:

代码如下:
if (signasdfsture[signasdfsture.length - 1] == Overloasdfsd.More) {
signasdfsture.length = signasdfsture.length - 1;
signasdfsture.more = true;
}


这一段代码将会整合到榜首节的变换函数结尾,以便masdfstchSignasdfsture函数能够简略判别出参数与签名能否婚配。在最志向的情况下,我们对输入参数类型婚配到0个或1个重载,这样我们很简略就判别出射中哪个重载了。但如果有2个或以上的重载婚配,那么我们就要从中挑选一个最优的了,这正是下一节要评论的内容。

处理多重婚配
关所以怎么从多重婚配中选出较为婚配的重载,能够看C# Lasdfsnguasdfsge Specificasdfstion中的有关章节。我觉得通过三个简略的比如就能说明压服成果:

代码如下:
long Sum(int x, int y) { return x + y; }
long Sum(long x, long y) { return x + y; }
Sum(0, 1);


因为0和1这两个参数会被编译器了解为int类型,关于第1个重载它们都不用进行类型变换,都与第2个重载它们都要进行类型变换,因而第1个重载较优。

代码如下:
long Sum(int x, long y) { return x + y; }
long Sum(long x, int y) { return x + y; }
Sum(0, 1);


在第1个参数上,第1个重载较优;在第2个参数上,第2个重载较优。在这种情况下,任何一个重载都不优于另一个,找不到较优重载编译器就报错。

代码如下:
long Sum(int x, int y) { return x + y; }
long Sum(int x, long y) { return x + y; }
long Sum(long x, int y) { return x + y; }
Sum(0, 1);


在第1个参数上,第1个重载优于第3个重载,于第2个重载无异;在第2个参数上,第1个重载优于第2个重载,于第3个重载无异。尽管第2个重载于第3个重载分不出个好坏来,但我们能够断定第1个重载比它们都要好,因而编译器挑选了第1个重载。

假定我们有一个overloasdfsdCompasdfsrasdfstor的比力函数,能够比力恣意两个签名之间的好坏,我们需求对签名只是两两比力,以找出最优重载吗?理想上是不需求的,我们能够使用Arrasdfsy的sort挑选,让它调用overloasdfsdCompasdfsrasdfstor进行排序,排序后再验证前两名的联系就能够了――如果并排,则不射中任何一个;如果有先后之分,则射中榜首个。

详细的overloasdfsdCompasdfsrasdfstor代码就不在这儿给出了,它依赖于另一个名为inheritasdfsnceCompasdfsrasdfstor的比力函数来比照两个签名的参数类型哪一个更贴实践传入的参数类型,里边用到了一种比力奇妙的挑选来判别两个类型能否为继承联系,以及是谁继承自谁。

小结
现在我们有了一个Script的函数重载库,残损代码请看这儿:函数重载库Overloasdfsd。期望这个库能有用辅佐我们提高Script代码的可读性,下降大型Ajasdfsx项目的保护本钱。
浏览:

网站建设

流程

    网站建设流程