对于这个argunments,估计很多同学都有见过,但是好像用的不是很多,很多人对他一知半解,那么今天我们就来说说argument对象以及有什么作用(欢迎大家补充)
什么是 argunments ?
在JS中arguments是一个类似Array的存在,但是他不等同于Array。arguments对象不能显式的创建,它只有在函数开始时才可用。它可以像访问数组那样去访问每一个子元素。
例如,在函数 sayHi() 中,第一个参数是 message。用 arguments[0] 也可以访问这个值,即第一个参数的值(第一个参数位于位置 0,第二个参数位于位置 1,依此类推)。
因此,无需明确命名参数,就可以重写函数:
function sayHi() {
if (arguments[0] == "bye") {
return;
}
alert(arguments[0]);
}
检测参数的个数
还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可。
下面的代码将输出每次调用函数使用的参数个数:
function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45);//2
howManyArgs();//0
howManyArgs(12);//1
JS重载
首先我们来看一段代码:
function overLoading() {
// 根据arguments.length,对不同的值进行不同的操作
switch(arguments.length) {
case 0:
/*操作1的代码写在这里*/
break;
case 1:
/*操作2的代码写在这里*/
break;
case 2:
/*操作3的代码写在这里*/
//后面还有很多的case......
}
}
这里就是一个js的重载,通过对于arguments属性length值进行判断,对不同的操作进行不同的判断进行执行
下面我们来看看一个升级版的
var people = {
values: ["Dean Edwards", "Sam Stephenson", "Alex Russell", "Dean Tom"]
};
我们希望people对象拥有一个find方法,当不传任何参数时,就会把people.values里面的所有元素返回来;当传一个参数时,就把first-name跟这个参数匹配的元素返回来;当传两个参数时,则把first-name和last-name都匹配的才返回来。因为find方法是根据参数的个数不同而执行不同的操作的,所以,我们希望有一个addMethod方法,能够如下的为people添加find的重载:
addMethod(people, "find", function() {}); /*不传参*/
addMethod(people, "find", function(a) {}); /*传一个*/
addMethod(people, "find", function(a, b) {}); /*传两个*/
这时候问题来了,这个全局的addMethod方法该怎么实现呢?John Resig的实现方法如下,代码不长,但是非常的巧妙:
function addMethod(object, name, fn) {
var old = object[name]; //把前一次添加的方法存在一个临时变量old里面
object[name] = function() { // 重写了object[name]的方法
// 如果调用object[name]方法时,传入的参数个数跟预期的一致,则直接调用
if(fn.length === arguments.length) {
return fn.apply(this, arguments);
// 否则,判断old是否是函数,如果是,就调用old
} else if(typeof old === "function") {
return old.apply(this, arguments);
}
}
}
现在,我们一起来分析一个这个addMethod函数,它接收3个参数,第一个为要绑定方法的对象,第二个为绑定的方法名称,第三个为需要绑定的方法(一个匿名函数)。函数体的的分析已经在注释里面了。
//addMethod
function addMethod(object, name, fn) {
var old = object[name];
object[name] = function() {
if(fn.length === arguments.length) {
return fn.apply(this, arguments);
} else if(typeof old === "function") {
return old.apply(this, arguments);
}
}
}
var people = {
values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};
/* 下面开始通过addMethod来实现对people.find方法的重载 */
// 不传参数时,返回peopld.values里面的所有元素
addMethod(people, "find", function() {
return this.values;
});
// 传一个参数时,按first-name的匹配进行返回
addMethod(people, "find", function(firstName) {
var ret = [];
for(var i = 0; i < this.values.length; i++) {
if(this.values[i].indexOf(firstName) === 0) {
ret.push(this.values[i]);
}
}
return ret;
});
// 传两个参数时,返回first-name和last-name都匹配的元素
addMethod(people, "find", function(firstName, lastName) {
var ret = [];
for(var i = 0; i < this.values.length; i++) {
if(this.values[i] === (firstName + " " + lastName)) {
ret.push(this.values[i]);
}
}
return ret;
});
// 测试:
console.log(people.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(people.find("Dean Edwards")); //["Dean Edwards"]