在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ arguments 對象
arguments 對象
類型轉(zhuǎn)換
構(gòu)造函數(shù)
instanceof 操作符
自動分號插入
為什么不要使用 eval
對象使用和屬性
作用域與命名空間
this 的工作原理
typeof 操作符
相等與比較
閉包和引用
數(shù)組遍歷與屬性
Array 構(gòu)造函數(shù)
原型
hasOwnProperty 函數(shù)
undefined 和 null
函數(shù)聲明與表達式
setTimeout 和 setInterval
for in 循環(huán)

arguments 對象

JavaScript 中每個函數(shù)內(nèi)都能訪問一個特別變量 arguments。這個變量維護著所有傳遞到這個函數(shù)中的參數(shù)列表。

注意: 由于 arguments 已經(jīng)被定義為函數(shù)內(nèi)的一個變量。 因此通過 var 關(guān)鍵字定義 arguments 或者將 arguments 聲明為一個形式參數(shù), 都將導(dǎo)致原生的 arguments 不會被創(chuàng)建。

arguments 變量不是一個數(shù)組(Array)。 盡管在語法上它有數(shù)組相關(guān)的屬性 length,但它不從 Array.prototype 繼承,實際上它是一個對象(Object)。

因此,無法對 arguments 變量使用標準的數(shù)組方法,比如 push, pop 或者 slice。 雖然使用 for 循環(huán)遍歷也是可以的,但是為了更好的使用數(shù)組方法,最好把它轉(zhuǎn)化為一個真正的數(shù)組。

轉(zhuǎn)化為數(shù)組

下面的代碼將會創(chuàng)建一個新的數(shù)組,包含所有 arguments 對象中的元素。

    Array.prototype.slice.call(arguments);

這個轉(zhuǎn)化比較,在性能不好的代碼中不推薦這種做法。

傳遞參數(shù)

下面是將參數(shù)從一個函數(shù)傳遞到另一個函數(shù)的推薦做法。

    function foo() {
        bar.apply(null, arguments);
    }
    function bar(a, b, c) {
        // 干活
    }

另一個技巧是同時使用 callapply,創(chuàng)建一個快速的解綁定包裝器。

    function Foo() {}

    Foo.prototype.method = function(a, b, c) {
        console.log(this, a, b, c);
    };

    // 創(chuàng)建一個解綁定的 "method"
    // 輸入?yún)?shù)為: this, arg1, arg2...argN
    Foo.method = function() {

        // 結(jié)果: Foo.prototype.method.call(this, arg1, arg2... argN)
        Function.call.apply(Foo.prototype.method, arguments);
    };

譯者注:上面的 Foo.method 函數(shù)和下面代碼的效果是一樣的:

    Foo.method = function() {
        var args = Array.prototype.slice.call(arguments);
        Foo.prototype.method.apply(args[0], args.slice(1));
    };

自動更新

arguments 對象為其內(nèi)部屬性以及函數(shù)形式參數(shù)創(chuàng)建 gettersetter 方法。

因此,改變形參的值會影響到 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 對象總會被創(chuàng)建,除了兩個特殊情況 - 作為局部變量聲明和作為形式參數(shù)。

argumentsgetterssetters 方法總會被創(chuàng)建;因此使用 arguments 對性能不會有什么影響。 除非是需要對 arguments 對象的屬性進行多次訪問。

ES5 提示: 這些 getterssetters 在嚴格模式下(strict mode)不會被創(chuàng)建。

譯者注MDC 中對 strict mode 模式下 arguments 的描述有助于我們的理解,請看下面代碼:

    // 闡述在 ES5 的嚴格模式下 `arguments` 的特性
    function f(a) {
      "use strict";
      a = 42;
      return [a, arguments[0]];
    }
    var pair = f(17);
    assert(pair[0] === 42);
    assert(pair[1] === 17);

然而,的確有一種情況會顯著的影響現(xiàn)代 JavaScript 引擎的性能。這就是使用 arguments.callee。

    function foo() {
        arguments.callee; // do something with this function object
        arguments.callee.caller; // and the calling function object
    }

    function bigLoop() {
        for(var i = 0; i < 100000; i++) {
            foo(); // Would normally be inlined...
        }
    }

上面代碼中,foo 不再是一個單純的內(nèi)聯(lián)函數(shù) inlining譯者注:這里指的是解析器可以做內(nèi)聯(lián)處理), 因為它需要知道它自己和它的調(diào)用者。 這不僅抵消了內(nèi)聯(lián)函數(shù)帶來的性能提升,而且破壞了封裝,因此現(xiàn)在函數(shù)可能要依賴于特定的上下文。

因此強烈建議大家不要使用 arguments.callee 和它的屬性。

ES5 提示: 在嚴格模式下,arguments.callee 會報錯 TypeError,因為它已經(jīng)被廢除了。