让JavaScript轻松支持函数重载(Part 2

在"让 JavaScript 轻松支持函数重载 (Part 1 - 设计)"里,我们设计了一套能在JavaScript中描述函数重载的方法,这套方法依赖于一个叫做Overload的静态类,现在我们就来看看如何实现这个静态类。

识别文本签名

我们先来回顾一下上一篇文章中提到的Overload用例:

var extend = Overload
  .add("*, ...",
    function(target) { })
  .add("Boolean, *, ...",
    function(deep, target) { });

我们允许用户输入一个字符串,表示某一个重载的签名。在用户调用函数时,我们需要拿着用户输入的参数实例去跟签名上的每一个参数类型作比较,因此我们需要先把这个字符串转换为类型数组。也就是说,字符串"Boolean, Number, Array"应该转换为数组[Boolean, Number, Array]。

在进行转换之前,我们先要考虑处理两个特殊类型,就是代表任意类型的"*",和代表任意数量的"..."。我们可以为它们定义两个专有的类型,以便在Overload内对它们做出特殊的兼容性处理:

Overload.Any = function() {};
Overload.More = function() {};

在有了这两个类型之后,字符串"Boolean, *, ..."就会被正确转换为数组[Boolean, Overload.Any, Overload.More]。由于Overload.Any和Overload.More都是函数,自然也都可以看做类型。

在这两个类型得到正确处理后,我们就可以开始编写识别文本签名的转换函数了:

if (signature.replace(/(^\s+|\s+$)/ig, "") == "") {
  signature = [];
} else {
  signature = signature.split(",");
  for (var i = 0; i < signature.length; i++) {
    var typeExpression = signature[i].replace(/(^\s+|\s+$)/ig, "");
    var type = null;
    if (typeExpression == "*") {
      type = Overload.Any;
    } else if (typeExpression == "...") {
      type = Overload.More;
    } else {
      type = eval("(" + typeExpression + ")");
    }
    signature[i] = type;
  }
}

我想这段代码相当容易理解,因此就不再解释了。我第一次写这段代码时忘记写上面的第一个if了,导致空白签名字符串""无法被正确识别为空白签名数组[],幸好我的unit test代码第一时间发现了这个缺陷。看来编写unit test代码还是十分重要的。

时间: 2024-09-06 18:13:49

让JavaScript轻松支持函数重载(Part 2的相关文章

让JavaScript轻松支持函数重载(Part 1

JavaScript支持重载吗? JavaScript支持函数重载吗?可以说不支持,也可以说支持.说不支持,是因为JavaScript不能好像其它原生支持函数重载的语言一样,直接写多个同名函数,让编译器来判断某个调用对应的是哪一个重载.说支持,是因为JavaScript函数对参数列表不作任何限制,可以在函数内部模拟对函数重载的支持. 实际上,在很多著名的开源库当中,我们都可以看到函数内部模拟重载支持的设计.例如说jQuery的jQuery.extend方法,就是通过参数类型判断出可选参数是否存在

让JavaScript 轻松支持函数重载 (Part 1 - 设计)_javascript技巧

JavaScript支持重载吗? JavaScript支持函数重载吗?可以说不支持,也可以说支持.说不支持,是因为JavaScript不能好像其它原生支持函数重载的语言一样,直接写多个同名函数,让编译器来判断某个调用对应的是哪一个重载.说支持,是因为JavaScript函数对参数列表不作任何限制,可以在函数内部模拟对函数重载的支持. 实际上,在很多著名的开源库当中,我们都可以看到函数内部模拟重载支持的设计.例如说jQuery的jQuery.extend方法,就是通过参数类型判断出可选参数是否存在

让 JavaScript 轻松支持函数重载 (Part 2 - 实现)_javascript技巧

识别文本签名 我们先来回顾一下上一篇文章中提到的Overload用例: 复制代码 代码如下: var extend = Overload .add("*, ...", function(target) { }) .add("Boolean, *, ...", function(deep, target) { }); 我们允许用户输入一个字符串,表示某一个重载的签名.在用户调用函数时,我们需要拿着用户输入的参数实例去跟签名上的每一个参数类型作比较,因此我们需要先把这个

javascript中没有函数重载的概念实例讲解

  这篇文章主要介绍了通过实例理解javascript中没有函数重载的概念,十分的简单易懂,需要的朋友可以参考下 将函数名想象为指针,也有助于理解为什么ECMAScript中没有函数重载的概念.如下例子: 代码如下: function addSomeNum(num) { return num+100; } function addSomeNum(num) { return num+200; } var result=addSomeNum(100);//300 显然,这个例子中声明了两个同名函数,

JavaScript中的函数重载深入理解_javascript技巧

在JavaScript中有一种特殊的数据类型---Function类型,JavaScript的每个函数都是Function类型的实例.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. <pre name="code" class="html">function sum(num1,num2) { return num1 +num2; } alert(sum(10,10)); //20 var other = sum; ale

通过实例理解javascript中没有函数重载的概念_javascript技巧

将函数名想象为指针,也有助于理解为什么ECMAScript中没有函数重载的概念.如下例子: 复制代码 代码如下: function addSomeNum(num) {     return num+100; } function addSomeNum(num) {     return num+200; } var result=addSomeNum(100);//300 显然,这个例子中声明了两个同名函数,而结果则是后面的函数覆盖了前面的函数.以上代码实际上与下面的代码是一致的. 复制代码 代

Javascript函数重载的例子介绍

js本身不支持重载,因为方法调用只与方法名相关,而不计较参数的数量和类型,也正是这个特点,我们可以用更简单的方法实现重载. 我们可以通过数组arguments来获取变量,再根据arguments.length来执行不同的操作. 简例: function getSum(){     //这是计算总和的函数     var sum=0;     for(var i=0;i<arguments.length;i++){         sum+=arguments[i];     }     retu

JS函数重载的解决方案_javascript技巧

在面向对象的编程中,很多语言都支持函数重载,能根据函数传递的不同个数.类型的参数来做不同的操作,JS对它却不支持,需要我们额外做些小动作. 在JS的函数执行上下文中有一个名为arguments的有意思的变量,它以数组的形式存储了函数执行时传递过来的所有参数,即使函数定义没有定义这 么多个形参.还有一个特别之处就是跟Array类型相比,arguments变量有且只有一个length属性,Array的方法,例如push.pop 等,它并不具备,它只是一个"伪数组":具有length属性,存

C语言实现函数重载

函数重载 大家都知道 C++ 等支持面向对象的语言支持函数重载,那么编译器是如何辨别这些函数的呢? CPP如何实现重载 C++ 实现函数重载很大程度上依赖与编译器对函数名的 Mangling(损坏,破坏),即 C++ 的源代码被编译后同名的重载函数名字会被破坏,一般是在原函数名前后加上特定的字符串(g++编译器中通过在函数名后面添加参数的后缀),以区分不同重载函数,然后在调用的时候根据参数的不同选择合适的函数,如下代码说明了编译器是如何处理普通函数重载的 几个同名的重载函数仍然是不同的函数,编译