arguments
2019-07-24 本文已影响0人
haha2333
js函数不能像传统意义上那样实现函数重载。所谓的函数重载就是:为一个函数编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。执行时判断参数个数,哪个函数参数个数吻合,则调用哪个
function aa(){
console.log("a")
}
function aa(b){
console.log("b")
}
aa() //b
但是在js中后面声明的函数定义会覆盖前面的,所以不存在函数重载。
那么js进行函数重载是依靠什么的呢?
arguments
它是JS的一个内置对象,每一个函数都有一个arguments对象,它包括了函数实际被传入的参数,用法与数组一样,但它却不是数组。使用instanceof会报错
比如访问传入函数的第一个参数:arguments[0]
传入参数的个数:arguments.length
这样不需要指出参数名,也可以访问他们
function test() {
var s = "";
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
s += arguments[i] + ",";
}
return s;
}
test("name", "age");
输出结果:
name,age
具体实现函数重载
函数的 length 属性,返回的是函数定义时形参的个数
object:要绑定方法的对象,
name:绑定的方法名称,
fn:需要绑定的方法
每调用一次 addMethod 函数,就会产生一个 old,形成一个闭包。
function addMethod (object, name, fn) {
// 先把原来的object[name] 方法,保存在old中
var old = object[name];
// 重新定义 object[name] 方法
object[name] = function () {
// 如果函数需要的参数 和 实际传入的参数 的个数相同,就直接调用fn
if (fn.length === arguments.length) {
return fn.apply(this, arguments);
// 如果不相同,判断old 是不是函数,
// 如果是就调用old,也就是刚才保存的 object[name] 方法
} else if (typeof old === "function") {
return old.apply(this, arguments);
}
}
}
使用:
find0、find1、find2方法自己定义
// 给 users 对象添加处理 没有参数 的方法
addMethod(users, "find", find0);
// 给 users 对象添加处理 一个参数 的方法
addMethod(users, "find", find1);
// 给 users 对象添加处理 两个参数 的方法
addMethod(users, "find", find2);
// 测试:
console.log(users.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(users.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(users.find("Dean","Edwards")); //["Dean Edwards"]
把arguments转换成一个真正的数组
var args = Array.prototype.slice.call(arguments);
创建引用自身的函数
callee属性是 arguments 对象的一个成员,callee 属性的初始值就是正被执行的 Function 对象。实现匿名的递归函数。
var sum = function (n) {
if (1 == n) {
return 1;
} else {
return n + arguments.callee(n - 1);
}
}
alert(sum(6)); //21
注意点:
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1); //10 2
第一个fn()自执行,没有上下文调用,所以this指向window,第二个arguments[0]()
即是arguments[0] () => fn() ,这里this执行的是arguments这个对象,所以输出值为arguments的长度2