`

JavaScript实现可变参数函数

阅读更多

使用javascript类库函数时,经常会遇到一个函数,可以使用不同个数的参数的情况

比如:

exp(var1) exp(var1, var2)

 

 

但是在实际编写javascript函数时,

函数不能同名,所以不可能是不同参数个数分开写;

参数个数必须符合函数的设置,所以函数声明里有的就必须有,不可能调用时写少几个;

……

这个问题是困扰了很久了,一直不知道为什么?!

今天一早在看别人代码,无意中竟然看到了~

 

原来不是在函数声明中声明参数个数,而是在函数里直接接收使用,那怎么接收呢?

就是 arguments 了可以500%提高开发效率的前端UI框架!

arguments虽然不是数组,但可以当作数组使用,下标由 0 开始,所以:

arguments[0] 表示接收的第一个参数
arguments[1] 表示接收的第二个参数
……
如此类推……

这样就可以实现不同参数调用同一个函数了~

当然,前提是函数设置了对该参数的处理方法,不然还是白搭

顺便搜索了一下arguments的介绍,一并贴出:


arguments 属性
为当前执行的 function 对象返回一个arguments 对象。

function.arguments

function 参数是当前执行函数的名称,可以省略。

说明
通过 arguments 属性,函数可以处理可变数量的参数。 arguments 对象的 length 属性包含了传递给函数的参数的数目。对于arguments 对象所包含的单个参数,其访问方法与数组中所包含的参数的访问方法相同。

示例
下面的例子说明了 arguments 属性的用法: 可以500%提高开发效率的前端UI框架!

function ArgTest(){
    var i, s, numargs = arguments.length;
    s = numargs;
    if (numargs < 2)
        s += " argument was passed to ArgTest. It was ";
    else
         s += " arguments were passed to ArgTest. They were " ;
    for (i = 0; i < numargs; i++)
{
s += arguments[i] + " ";
}
return(s);
}

 

 

巧用arguments

    在 Javascript 的函数中有个名为 arguments 的类数组对象。它看起来是那么的诡异而且名不经传,但众多的 Javascript 库都使用着它强大的功能。所以,它的特性需要每个 Javascript 程序员去熟悉它。

它以类似数组的形式保存了当前调用的参数。而它实际上并不是个数组,使用 typeof arguments 语句尝试会返回“object”(对象),所以它不能像 Array 一样使用 push 和 pop 等方法。即便如此,仍然可以使用下标以及长度属性(length)获取它的值。

编写灵活的函数
   虽看起来名不经传,但的确 arguments 是非常有用的对象。比如,你可以让函数处理不定数目的参数。在 Dean Edwards 写的 base2 库中,有个叫 format 的函数充分发挥了这一特性: 可以500%提高开发效率的前端UI框架!

function format(string) {
    var args = arguments;
    var pattern = new RegExp("%([1-" + arguments.length + "])", "g");
    return String(string).replace(pattern, function(match, index) {
       return args[index];
    });
};

 

 

   replace这个函数的第二个参数可以为一个函数,函数的第一个参数可以为匹配了的文本,第二个参数为第几个匹配的值,返回值为要进行替换的文本

   这个函数实现了模板替换,你可以在要动态替换的地方使用 %1 到 %9 标记,然后其余的参数就会依次替换这些地方。例如:format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");
   上面的脚本就会返回"And the papers want to know whose shirt you wear" 。
   在这里需要注意的是,即便在 format 函数定义中,我们仅定义了个名为 string 的参数。而 Javascript 不管函数自身定义的参数数量,它都允许我们向一个函数传递任意数量的参数,并将这些参数值保存到被调用函数的 arguments 对象中。

 

转换成实际数组
   虽然 arguments 对象并不是真正意义上的 Javascript 数组,但是我们可以使用数组的 slice 方法将其转换成数组,类似下面的代码

var args = Array.prototype.slice.call(arguments);

 

 

call(obj,当前函数使用的参数列表)可以500%提高开发效率的前端UI框架!

   call 方法第一个参数为一个对象,这个传进去的对象将调用slice函数.因为arguments不是一个数组,所以不能直接调用slice方法,所以只能使用 ''对象冒充''方法了。这样,数组变量 args 包含了所有 arguments 对象包含的值。

 

使参数构建函数
   使用 arguments 对象能够简短我们编写的 Javascript 代码量。下面有个名为 makeFunc 的函数,它根据你提供的函数名称以及其他任意数目的参数,然后返回个匿名函数。此匿名函数被调用时,合并的原先被调用的参数,并交给指定的函数运行然后返 回其返回值。

function makeFunc() {
    var args = Array.prototype.slice.call(arguments);
    var func = args.shift();
    return function() {
      return func.apply(null,   args.concat(Array.prototype.slice.call(arguments)));};
}

 

 

 

    arguments 有一个不可枚举的属性callee(不能用for in读出,可用HasOwnProterty(name)来判断),arguments.callee为正被执行的 Function 对象。slice时己把当前函数指针copy了过去,所以args的第一个元素为函数类型

    makeFunc 的第一个参数指定需要调用的函数名称(是的,在这个简单的例子中没有错误检查),获取以后从 args 中删除。makeFunc 返回一个匿名函数,它使用函数对象的(Function Object)apply 方法调用指定的函数。

    apply 方法的第一个参数指定了作用域,基本上的作用域是被调用的函数。不过这样在这个例子中看起来会有点复杂,所以我们将其设定成 null ;其第二个参数是个数组,它指定了其调用函数的参数。makeFunc 转换其自身的 arguments 并连接匿名函数的 arguments,然后传递到被调用的函数。

   有种情况就是总是要有个输出的模板是相同的,为了节省每次是使用上面提到的 format 函数并指定重复的参数,我们可以使用 makeFunc 这个工具。它将返回一个匿名函数,并自动生成已经指定模板后的内容: 可以500%提高开发效率的前端UI框架!

var majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1.");

 

 


你可以像这样重复指定 majorTom 函数:

majorTom("stepping through the door");
majorTom("floating in a most peculiar way");

 

 


那么当每次调用 majorTom 函数时,它都会使用第一个指定的参数填写已经指定的模板。例如上述的代码返回:

"This is Major Tom to ground control. I'm stepping through the door."
"This is Major Tom to ground control. I'm floating in a most peculiar way."

 

自引用的函数
   您可能会认为这很酷,先别急着高兴,后面还有个更大的惊喜。它(arguments)还有个其他非常有用的属性:callee 。arguments.callee 包含了当前调用函数的被引用对象。那么我们如何使用这玩意做些的事情?arguments.callee 是个非常有用的调用自身的匿名函数。

   下面有个名为 repeat 的函数,它的参数需要个函数引用和两个数字。第一个数字表示运行的次数,而第二个函数定义运行的间隔时间(毫秒为单位)。下面是相关的代码: 可以500%提高开发效率的前端UI框架!

function repeat(fn, times, delay) {
    return function() {
        if (times-- > 0) {
            fn.apply(null, arguments);
            var args = Array.prototype.slice.call(arguments);
            var self = arguments.callee;
            setTimeout(function(){self.apply(null,args)}, delay);
        }
   };
}

 

 

   repeat 函数使用 arguments.callee 获得当前引用,保存到 self 变量后,返回个匿名函数重新运行原本被调用的函数。最后使用 setTimeout 以及配合个匿名函数实现延迟执行。

   作为个简单的说明,比如会在通常的脚本中,编写下面的提供个字符串并弹出个警告框的简单函数:

function comms(s) {
    alert(s);
}

 

 


   好了,后来我改变了我的想法。我想编写个“特殊版本”的函数,它会重复三次运行每次间隔两秒。那么使用我的 repeat 函数,就可以像这样做到:

var somethingWrong = repeat(comms, 3, 2000);
somethingWrong("Can you hear me, major tom?");

 

 


结果就犹如预期的那样,弹出了三次警告框每次延时两秒。可以500%提高开发效率的前端UI框架!

最后,arguments 即便不会经常被用到,甚至显得有些诡异,但是它上述的那些惊艳的功能(不仅仅是这些!)值得你去了解它。

0
0
分享到:
评论

相关推荐

    javascript 利用arguments实现可变长参数

    javascript arguments解释,实现可变长参数。 在C#中,有可变长参数params[],但是在js中,如何实现这种可变参数呢? 一、可变长参数 arguments是非常好的解决方法,一直不知道javascript有这个东西。 先来看看应用...

    JavaScript参数个数可变的函数举例说明

    JavaScript允许一个函数传递个数可变的参数,因为有arguments这个内置对象,它一个函数传递的所有参数的数组

    Python 函数的参数-在函数内部使用方法修改可变参数会影响外部实参

    Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。 Python还被语言流行指数的编译器Tiobe将它被评为最受欢迎的编程语言,20多年来首次将Python置于...

    轻松学习JavaScript函数中的 Rest 参数

    JavaScript函数允许未知数量的函数参数。在ECMAScript 6之前,JavaScript有一个变量来访问这些未知或可变数目的参数,这是一个类似数组的对象,并非一个数组。细想以下代码来理解arguments变量: function add(){ ...

    用函数式编程技术编写优美的 JavaScript

    函数式编程语言在学术领域已经存在相当长一段时间了,但是从历史上看,它们没有丰富的工具和库可供使用。随着 .NET 平台上的 Haskell 的出现,函数式编程变得更加流行。一些传统的编程语言,例如 C++ 和 JavaScript...

    深入学习JavaScript中的Rest参数和参数默认值

    通常,我们需要创建一个可变参数的函数,可变参数是指函数可以接受任意数量的参数。例如,String.prototype.concat 可以接受任何数量的字符串作为参数。使用 Rest 参数,ES6 为我们提供一种新的方式来创建可变参数的...

    zvargs:Zhou 的 node.js 模块,用于处理函数的可变参数

    函数的可变参数原型是指混合了强制参数和可选参数的参数原型。 下面是一个例子: function func(arg0:number, [arg1:Array], [arg2:string], arg3:function, arg4:RegExp|string, ...); 其中,方括号中的参数是可...

    Node.js-immutable-Javascript不可变的持久化数据集合

    immutable - Javascript不可变的持久化数据集合

    探讨JavaScript中的Rest参数和参数默认值

    通常,我们需要创建一个可变参数的函数,可变参数是指函数可以接受任意数量的参数。例如,String.prototype.concat 可以接受任何数量的字符串作为参数。使用 Rest 参数,ES6 为我们提供一种新的方式来创建可变参数的...

    详解JavaScript中常用的函数类型

    1、可变函数 [removed] function show(){ alert&#40;第一个。。。&#41;; } function show(str){ alert&#40;第二个&#41;; } function show(a,b){ alert&#40;第三个。。。&#41;; alert&#40;a+:+b&#41;; ...

    使用html+css+javascript实现一个漂亮、炫酷的表白页面,给出源码

    使用html+css+javascript实现一个漂亮、炫酷的表白页面,给出源码,该页面使用 CSS 的 radial-gradient 函数实现了爱心背景,并且使用了 filter 属性和 text-shadow 属性来增加页面的视觉效果。同时,使用了 CSS 的 ...

    javascript实现简单的可随机变色网页计算器示例

    本文实例讲述了javascript实现简单的可随机变色网页计算器。分享给大家供大家参考,具体如下: 该程序能实现简单的加、减、乘、除、求余,页面还添加了随机变换颜色的功能。 运行效果图如下: 完整实例代码如下: ...

    JAVASCRIPT 写一个函数 , 用户输入任意两个数字的任意算数运算 (简单的计算器小功能) , 并能弹出运算后的结果

    var num1 = prompt('请输入第一个数:'); var re = prompt('请输入你要进行的运算符:'); var num2 = prompt('请输入第二个数:'); function getSum(num1,re,num2,) { switch (re) { case '+': ...

    JavaScript权威指南(第6版)

    3.7 不可变的原始值和可变的对象引用 3.8 类型转换 3.9 变量声明 3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 ...

    javascript的currying函数介绍

    curring的概念将函数式编程的概念和默认参数以及可变参数结合在一起.一个带n个参数,curried的函数固化第一个参数为固定参数,并返回另一个带n-1个参数的函数对象,分别类似于LISP的原始函数car和cdr的行为。currying能...

    客户端统一验证JavaScript函数库及示例源码

    参数myform指代验证的表单,可以比作验证树DOM的根,之后的JavaScript会遍历所有元素(elements),逐个检验,若没有设置验证则直接跳过,若有一个验证不通过,都不会将表单提交,并将光标定位到该处(focus()),若有...

    JavaScript权威指南(第6版)(附源码)

    3.7 不可变的原始值和可变的对象引用 3.8 类型转换 3.9 变量声明 3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 ...

Global site tag (gtag.js) - Google Analytics