理解javascript的caller,callee,ca…

来源:互联网 发布:乌云整站源码 编辑:程序博客网 时间:2024/05/17 09:17
arguments 对象
JavaScript 中每个函数内都能访问一个特别变量arguments。这个变量维护着所有传递到这个函数中的参数列表。
    注意: 由于arguments 已经被定义为函数内的一个变量。
    因此通过 var关键字定义 arguments 或者将 arguments 声明为一个形式参数,
    都将导致原生的arguments 不会被创建。
arguments 变量不是一个数组(Array)。
尽管在语法上它有数组相关的属性 length,但它不从 Array.prototype继承,实际上它是一个对象(Object)。
因此,无法对 arguments 变量使用标准的数组方法,比如 push, pop 或者slice。
虽然使用 for 循环遍历也是可以的,但是为了更好的使用数组方法,最好把它转化为一个真正的数组。
转化为数组
下面的代码将会创建一个新的数组,包含所有 arguments 对象中的元素。
Array.prototype.slice.call(arguments);
这个转化比较慢,在性能不好的代码中不推荐这种做法。
传递参数
下面将参数从一个函数传递到另一个函数,是推荐的做法。
function foo() {
   bar.apply(null, arguments);
}
function bar(a, b, c) {
    // do stuffhere
}
另一个技巧是同时使用 call 和 apply,创建一个快速的解绑定包装器。
function Foo() {}
Foo.prototype.method = function(a, b, c) {
   console.log(this, a, b, c);
};
// Create an unbound version of"method" 
// 输入参数为: this, arg1, arg2...argN
Foo.method = function() {
    // 结果:Foo.prototype.method.call(this, arg1, arg2...argN)
   Function.call.apply(Foo.prototype.method,arguments);
};
译者注:上面的 Foo.method 函数和下面代码的效果是一样的:
Foo.method = function() {
    var args =Array.prototype.slice.call(arguments);
   Foo.prototype.method.apply(args[0],args.slice(1));
};
自动更新
arguments 对象为其内部属性以及函数形式参数创建 getter 和 setter 方法。
因此,改变形参的值会影响到 arguments 对象的值,反之亦然。
function foo(a, b, c) {
    arguments[0]= 2;
    a; //2                                                           

    b =4;
   arguments[1]; // 4

    var d =c;
    d =9;
    c; //3
}
foo(1, 2, 3);
性能真相
arguments 对象总会被创建,除了两个特殊情况 - 作为局部变量声明和作为形式参数。
而不管它是否有被使用。
arguments 的 getters 和 setters 方法总会被创佳;因此使用 arguments对性能不会有什么影响。
除非是需要对 arguments 对象的属性进行多次访问。
原创粉丝点击