天天成长一点,多年之后你会发现你很牛。 javascript
使用javascript类库函数时,常常会遇到一个函数,可使用不一样个数的参数的状况 java
好比:exp(var1) exp(var1, var2) 程序员
可是在实际编写javascript函数时, 数组
函数不能同名,因此不多是不一样参数个数分开写; app
参数个数必须符合函数的设置,因此函数声明里有的就必须有,不可能调用时写少几个; 函数
…… 工具
这个问题是困扰了好久了,一直不知道为何?! 测试
今天一早在看别人代码,无心中居然看到了~
spa
原来不是在函数声明中声明参数个数,而是在函数里直接接收使用那怎么接收呢?
prototype
就是 arguments 了
arguments虽然不是数组,但能够看成数组使用,下标由 0 开始,因此:
arguments[0] 表示接收的第一个参数这样就能够实现不一样参数调用同一个函数了~
固然,前提是函数设置了对该参数的处理方法,否则仍是白搭
顺便搜索了一下arguments的介绍,一并贴出:
引用内容 引用内容
arguments 属性
为当前执行的 function 对象返回一个arguments 对象。
function.arguments
function 参数是当前执行函数的名称,能够省略。
说明
经过 arguments 属性,函数能够处理可变数量的参数。 arguments 对象的 length 属性包含了传递给函数的参数的数目。对于arguments 对象所包含的单个参数,其访问方法与数组中所包含的参数的访问方法相同。
示例
下面的例子说明了 arguments 属性的用法:
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 程序员去熟悉它。
在每一个函数中,都有个名为 arguments 的变量,它以相似数组的形式保存了当前调用的参数。而它实际上并非个数组,使用 typeof arguments 语句尝试会返回“object”(对象),因此它不能像 Array 同样使用 push 和 pop 等方法。即使如此,仍然可使用下标以及长度属性(length)获取它的值。
编写灵活的函数
虽看起来名不经传,但的确 arguments 是很是有用的对象。好比,你可让函数处理不定数目的参数。在 Dean Edwards 写的 base2 库中,有个叫 format 的函数充分发挥了这一特性:
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,当前函数使用的参数列表)
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 这个工具。它将返回一个匿名函数,并自动生成已经指定模板后的内容:
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 的函数,它的参数须要个函数引用和两个数字。第一个数字表示运行的次数,而第二个函数定义运行的间隔时间(毫秒为单位)。下面是相关的代码:
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?");
结果就犹如预期的那样,弹出了三次警告框每次延时两秒。
最后,arguments 即使不会常常被用到,甚至显得有些诡异,可是它上述的那些惊艳的功能(不只仅是这些!)值得你去了解它。
undefined ≠ null
null 是一个对象,undefined是一个属性、方法或变量。存在null是由于对象被定义。若是对象没有被定义,而测试它是不是null,但由于没有被定义,它没法测试到,并且会抛出错误。
if (myObject !== null && typeof(myObject) !== 'undefined') { //若是myObject是undefined,它不能测试是否为null,并且还会抛出错误 } if (typeof(myObject) !== 'undefined' && myObject !== null) { //处理myObject的代码 }