Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript的arguments及其子对象

  首先一个最大的问题是,arguments这个对象哪儿来的?也许有人会认为它是调用函数时引擎自带的一个局部变量,因为我们平时使用arguments的时候都是在函数中把它当作局部变量来使用的。事实上arguments是Function实例的属性,只是在调用时候会被作为局部变量来使用而已。这也是这个对象最吸引人的地方。在函数没有运行时我们也可以访问到它,只不过没运行时它的值是null而已。 function f(){
  alert(f.arguments==arguments); //true
};
alert("arguments" in f); //true
alert(f.arguments); //null
f();
  arguments这个对象的作用是保存函数在运行期间的一些参数。当我们调用函数时,传入的参数会在arguments中以拟数组方式储存。它和数组一样提供了length属性,但却没有数组的方法。因此它只是一个拟数组而不是真正的数组。不过虽然不是真正的数组,我们也依然可以让数组的方法去主动调用它,比如这样调用 function join(){
  return Array.prototype.join.call(arguments);
};
alert(join("a","b","c"));
  也可以把它当成数组,作为apply的参数来使用,比如一个获取最大值的函数 function max(){
  return Math.max.apply(null,arguments);
};
alert(max(5,2,7));
  这是它作为拟数组的性质,而这个arguments本身也有自己的性质。它的参数列表和对应的形参使用的是相同的数据地址,或者说形参就是某个arguuments参数列表项的别名。看下面代码就会明白 (function(a){
  a="次碳酸钴";
  alert(arguments[0]); //次碳酸钴
})("测试");
  这个例子中a和arguments[0]是共用的数据地址,所以给a赋值后arguments[0]的值也会改变。接着是arguments中一个关键的属性callee。这个callee指的就是函数自身,可以用一段代码来验证。
function f(){
  alert(arguments.callee===f); //true
};
f();
  我们经常会在匿名函数的递归中使用callee。由于匿名函数没有变量来保存它的句柄,所以只能在运行时候通过callee来获取,以实现递归。 (function(){
  console.log("次碳酸钴");
  setTimeout(arguments.callee,1000);
})();
  像上面这样每秒一次的慢递归,这种方法可以节省一个变量名,非常推荐使用。但是对于需要效率的递归就不建议这样使用,因为在某些引擎中对arguments处理是非常复杂的,这就会影响效率。这个问题在之前的文章“JavaScript调用堆栈对变量访问效率有影响!?”中有提到过。即使arguments什么都没做,只是被一个分号结束也是非常影响效率的,所以在需要高效的代码中尽量避免引入arguments。
  到这里arguments对象的内容就说完了,也许有人会问怎么不说caller呢?这个caller由于历史原因,现在的标准已经在arguments对象中废除了caller,而把caller这个对象定义到了Function实例的属性中。这样caller和arguments就变成了同级别的,这让它与arguments对象划清了关系。而且这个caller对象很不简单,所以今天就到这里,明天再来解释这个caller。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^