JS的arguments

1、前言

一、在函數調用的時候,瀏覽器每次都會傳遞進兩個隱式參數:數組

一個是函數的上下文對象this,另外一個則是封裝實參的類數組對象arguments瀏覽器

二、與其餘程序設計語言不一樣,ECMAScript不會驗證傳遞給函數的參數個數是否等於函數定義的參數個數。開發者定義的函數均可以接受任意個數的參數(但根據Netscape的文檔,最多可接受255個),而不會引起任何錯誤。任何遺漏的參數都會以undefined傳遞給函數,多餘的函數將忽略。函數

即參數從左向右進行匹配,若是實參個數少於形參,後面的參數對應賦值爲undefined。如:ui

function fn (a, b, c) {
    console.log(a, b, c); // 1 2 undefined
    // 函數對象的length屬性就是函數形參的個數
    console.log(fn.length); // 3
}
fn(1, 2);
複製代碼

2、arguments

一、描述

arguments的定義是對象,可是由於對象的屬性是無序的,而arguments是用來存儲實參的,是有順序的,它具有和數組相同的訪問性質及方式,並擁有數組長度屬性length,因此arguments是特殊的對象,又叫類數組對象,當咱們聽到類數組時就能夠知道說的是argumentsthis

arguments是一個類數組對象,用來存儲實際傳遞給函數的參數,使調用函數時不侷限於函數聲明所定義的參數列表。spa

function fn() {
    console.log(arguments);
    console.log(typeof arguments); // object
    console.log(toString.call(arguments)); // [object Arguments]
}
fn('name', 'age');
複製代碼

二、訪問實參和檢查實參個數

arguments訪問單個參數的方式與訪問數組元素的方式相同。例如arguments[0]arguments[1]arguments[n],在函數中不須要明確指出參數名,就能訪問它們。經過length屬性能夠知道實參的個數。prototype

function f2() {
    console.log(arguments[0]); // name
    console.log(arguments[1]); // age
    console.log(arguments.length); // 2
}
f2('name', 'age');
複製代碼

三、callee屬性

每個對象都有本身的屬性,而arguments有一個callee屬性,返回正被執行的Function對象。設計

function f3() {
    console.log(arguments.callee === f3); // true
}
f3('name', 'age');
複製代碼

四、arguments的修改

在正常的模式下,arguments對象是容許在運行時進行修改的。3d

function f4() {
    arguments[0] = 'sex';
    console.log(arguments[0]); // sex
}
f4('name', 'age');
複製代碼

五、轉化成真實數組

arguments是類數組對象,除了length屬性和索引元素以外沒有任何Array屬性。例如,它沒有 pop方法。可是它能夠被轉換爲一個真正的Array:code

function f5(){
    // 可使用slice來將arguments轉換爲真實數組
    var args1 = Array.prototype.slice.call(arguments);
    var args2 = [].slice.call(arguments);
    // 也可使用Array.from()方法或者擴展運算符來將arguments轉換爲真實數組
    var args3 = Array.from(arguments);
    var args4 = [...arguments];
}
f5('name', 'age');
複製代碼

3、應用

一、借用arguments.length能夠來查看實參和形參的個數是否一致

function fn (a, b, c) {
    if (fn.length != arguments.length) {
        console.log('形參和實參的個數不一致');
    } else{
        console.log('形參和實參的個數一致');
    }
}
fn(1, 2);
複製代碼

二、借用arguments.callee來讓匿名函數實現遞歸:

let sum = function (n) {
    if (n == 1) {
        return 1;
    } else {
        return n + arguments.callee(n - 1); // 5 4 3 2 1
    }
}
console.log(sum(6)); // 21
複製代碼

三、遍歷參數求和或者求最大值

function max () {
    var max = arguments[0];
    for (item of arguments) {
        if (item > max) {
            max = item;
        }
    }
    return max;
}
console.log(max(5, 3, 2, 9, 4)); // 9
複製代碼

四、模擬函數重載

重載函數是函數的一種特殊狀況,爲方便使用,C++容許在同一範圍中聲明幾個功能相似的同名函數,可是這些同名函數的形式參數(指參數的個數、類型或者順序)必須不一樣,也就是說用同一個函數完成不一樣的功能。

arguments對象判斷傳遞給函數的參數個數,便可模擬函數重載:

function doAdd() {
    if(arguments.length == 1) {
        console.log(arguments[0] + 5);
    } else if(arguments.length == 2) {
        console.log(arguments[0] + arguments[1]);
    }
}
doAdd(10);  // 15
doAdd(10, 20); // 30
複製代碼

4、總結

一、arguments是一個類數組對象,用來存儲實參;具備lengthcallee等屬性;能夠用arguments[0]這個形式訪問實參;能夠轉換爲真實數組。

二、arguments和函數相關聯,其只有在函數執行時可用,不能顯式建立。

三、arguments能夠用來遍歷參數;經過callee實現遞歸;也能夠模擬函數重載。

相關文章
相關標籤/搜索