完全理解JS--arguments
0.462018.05.15 15:45:31字数 1,001阅读 15,411
什么是arguments?
它是JS的一个内置对象,常被人们所忽略,但实际上确很重要,JS不像JAVA是显示传递参数,JS传的是形参,可以传也可以不传,若方法里没有写参数却传入了参数,该如何拿到参数呢,答案就是arguments了,在一些插件里通常这样使用。
每一个函数都有一个arguments对象,它包括了函数所要调的参数,通常我们把它当作数组使用,用它的length得到参数数量,但它却不是数组,使用instanceof查看下,若使用push添加数据将报错,代码如下:
(function(){
console.log([] instanceof Array)
console.log(arguments instanceof Array)
if(arguments.push) arguments.push('test')
})()
创建一个灵活的格式化函数
上面说了arguments可以使用函数使用数量不定的参数,下面看看它的一个实际应用:
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];
});
};
format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");
这里我借用了别人的一个例子,一个模板字符串,可以使用%1到%9等9个占位符,然后提供9个参数给这些占位符,最后替换生成真正的字符串。
上面的代码返回:“And the papers want to know whose shirt you wear”
把arguments转换成一个真正的数组
有时我们希望将它转换成真正的数组使用,可以使用下面的代码:
var args = Array.prototype.slice.call(arguments);
现在args就是一个标准的js数组了,可以使用数组的标准方法了。
通过arguments对象封装format函数
arguments允许我们去执行所有类型的js方法,下面通过一个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给makeFunc提供了你调用的函数的引用,它将第一个参数从arguments数组里移除,然后makeFunc返回了一个匿名函数去运行规定的方法。
apply的第一个参数是函数调用的范围,主要是函数内部关联部分所指向的,这里设为null,它的arguments是一个数组,即匿名函数调用时传入的参数,匿名函数将传入的参数串联到原参数对象args里组成完整的匿名函数所需要参数。
你需要输出一个模板,总是相同位置的字符发生改变,这样就可以使用makeFunc去生成一个模板函数,传入不同的参数多次调用生成不同的内容了。
var func = makeFunc(format, "I like %1 not %2.");
func("js", "java");
func("java", "python");
每一次调用func,它会同时调用format函数和第一个arguments,然后填充已有的模板。
执行结果如下:
"I like js not java."
"I like java not python."
这样封装format是不是很酷,不过arguments还有更多惊喜。
创建引用自身的函数
arguments.callee包括了一个函数的引用去创建一个arguments对象,它能让一个匿名函数很方便的指向本身。
下面的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获取一个引用,指向运行原始指令的函数。这样,匿名函数就可以再次调用自身,看看下面的调用:
var somethingWrong = repeat(function(s){console.log(s)}, 3, 2000);
somethingWrong("Can you hear me, major tom?");
可以看到somethingWrong函数的结果被打印了3次,每隔2秒。
arguments还有很多惊喜,非常值得我们去了解,欢迎加入前端交流群。
学习交流,请加群:867541922