js 中的 arguments 对象

    我一直对函数中的 arguments 对象非常的困惑, 前段时间仔细看了下犀牛书, 才感觉到, arguments 完全就是个坑爹的存在.

    好吧, 先小小地解释一下 什么是 arguments , 这个对象只有在函数中才有效, 它的内容是一个当前执行函数的参数数组, 举个例子:

 

    function test(a){
        alert(a);    // 3
        alert(arguments[0]);    // 3
        alert(arguments[1]);    // 6
        alert(arguments[2]);    // 7
    };
    test(3,6,7);

 

    这个函数在定义的时候, 只有一个参数 a, 但是调用的时候, 传入了三个参数, 此时的型参a 自然是赋值为3 ,但是另外两个传进来的参数也没有被丢失, 可以通过arguments 数组去访问它们, 传入了多少个参数, arguments对象的长度就为多大. 这个例子中, a 与 arguments[0] 的值实际是同一个对象. 可见在函数中访问参数的方法不止一种.

    arguments 对象是一个很管用的对象, 这让javascript 可以很自由地实现可变参,  但是也确实很坑爹, 因为它用起来很像一个数组, 但是从严格意义上将, 它却不是一个数组, 而只是拥有与数组相似的结构而已. 比如做一个很常见的数组分片操作:  arguments.slice(3, 4);

    这一句代码是一定会报错的,  因为对象不存在这个方法, 我在谷歌浏览器的调试工具中设个断点: 


    这个例子中, array 是一个普通的数组对象,  可见arguments 对象与普通数组的内部结构还是很像的, 也有length 属性, 但最大的不同就是原型(__proto__)指向的不同, 普通数组是用Array 构造函数生成的, 所以原型直接指向了 Array.prototype 这个对象, 所以可以调用这里面的原生方法, 而arguments 只是一个原始的Object 而已, 所以本身不支持任何数组操作. 不过, 群众的智慧是伟大的, 换种写法, 还是可以用原生的数组方法对arguments  进行操作的, 比如把 arguments.slice(3, 4) 写成Array.prototype.slice.call(arguments, 3, 4);

    这里直接访问数组原型中的slice 方法, 并把arguments 作为this 传进去, 这就像arguments自己去调用这个方法一样. slice 究竟是怎么执行的我们不知道, 但是猜也猜得出, 不过就是对内部元素的一些操作, 由于 arguments 内部结构和一个普通数组差不了多少, 所以这个方法对arguments 也是可用的. 其他数组方法也是一样的道理. 

 

 

    

 

posted @ 2012-06-14 23:15  jsckdao  阅读(306)  评论(0编辑  收藏  举报