arguments 是一個類似數組的對象, 對應於傳遞給函數的參數。
1. 描述
arguments對象是所有函數中可用的局部變量。你可以使用arguments對象在函數中引用函數的參數。此對象包含傳遞給函數的每個參數的條目,第一個條目的索引從0開始。例如,如果一個函數傳遞了三個參數,你可以參考它們如下:
arguments[0]
arguments[1]
arguments[2]
參數也可以被設置:
arguments[1] = 'new value';
arguments對象不是一個 Array
。它類似於數組,但除了 長度之外沒有任何數組屬性。例如,它沒有 pop方法。但是它可以被轉換為一個真正的數組::
let args = Array.prototype.slice.call(arguments);
let args = [].slice.call(arguments);
你還可以使用 Array.from()
方法或 spread 運算符將 arguments 轉換為真正的數組:
let args = Array.from(arguments);
let args = [...arguments];
對參數使用slice會阻止某些JavaScript引擎中的優化 (比如 V8 引擎 - 更多信息)。
如果你關心它們,嘗試通過遍歷arguments對象來構造一個新的數組。
另一種方法是使用 被忽視的/鄙視/輕視,/看不起 Array構造函數作為一個函數:
let args = ( arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments) );
如果 Array generics 可用的話,下面的代碼可以作為替代:
var args = Array.slice(arguments);
arguments
對象僅在函數內部有效,在函數外部調用 arguments 對象會出現一個錯誤。
arguments的typeof返回'object'。
console.log(typeof arguments); // 'object'
可以使用索引來確定各個arguments的類型。
console.log(typeof arguments[0]); //這將返回單個參數的typeof。
如果你調用一個函數,當這個函數的參數數量比它顯式聲明的參數數量更多的時候,你就可以使用 arguments
對象。這個技術對於參數數量是一個可變量的函數來說比較有用。 你可以用 arguments.length
來得到參數的數量,然后可以用 arguments
object 來對每個參數進行處理。 (想要得到函數簽名的參數數量, 請使用 Function.length
屬性。)
2. 屬性
-
arguments.callee
指向當前執行的函數。
-
arguments.caller
**指向調用當前函數的函數。
-
arguments.length
指向傳遞給當前函數的參數數量。
3. 例子
3.1. 例子: 定義一個連接幾個字符串的函數
這個例子定義了一個函數來連接字符串。這個函數唯一正式聲明了的參數是一個字符串,該參數指定一個字符作為銜接點來連接字符串。該函數定義如下:
function myConcat(separator) { var args = Array.prototype.slice.call(arguments, 1); return args.join(separator); }
你可以傳遞任意數量的參數到該函數,然后該函數會將每個參數作為一個條目來創建一個列表。
// returns "red, orange, blue" myConcat(", ", "red", "orange", "blue"); // returns "elephant; giraffe; lion; cheetah" myConcat("; ", "elephant", "giraffe", "lion", "cheetah"); // returns "sage. basil. oregano. pepper. parsley" myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
3.2. 例子: 定義一個創建HTML列表的方法
這個例子定義了一個函數通過一個字符串來創建HTML列表。這個函數唯一正式聲明了的參數是一個字符。當該參數為 "u
" 時,創建一個無序列表 (項目列表);當該參數為 "o
" 時,則創建一個有序列表 (編號列表)。該函數定義如下:
function list(type) { var result = "<" + type + "l><li>"; var args = Array.prototype.slice.call(arguments, 1); result += args.join("</li><li>"); result += "</li></" + type + "l>"; // end list return result; }
你可以傳遞任意數量的參數到該函數,然后該函數會將每個參數作為一個條目添加到第一個參數指定類型的列表當中。
var listHTML = list("u", "One", "Two", "Three"); /* listHTML is: "<ul><li>One</li><li>Two</li><li>Three</li></ul>" */
3.3. 剩余參數, 默認參數 和 解構賦值參數
arguments 對象可以與剩余參數、默認參數和結構賦值參數結合使用。
function foo(...args) { return args; } foo(1, 2, 3); // [1,2,3]
在嚴格模式下,剩余參數剩余參數、默認參數和結構賦值參數的存在不會改變 arguments 對象的行為,但是在非嚴格模式下就有所不同了。
當在非嚴格模式函數中 沒有包含 剩余參數、默認參數或結構賦值參數,那么 arguments 對象將會追蹤參數的變化,反之亦然。看下面的代碼:
function func(a) { arguments[0] = 99; // 更新了arguments[0] 同樣更新了a console.log(a); } func(10); // 99
並且
function func(a) { a = 99; // 更新了a 同樣更新了arguments[0] console.log(arguments[0]); } func(10); // 99
當在非嚴格模式函數中 包含有 剩余參數、默認參數或結構賦值參數,那么 arguments 對象將不會追蹤參數的變化,反之亦然。相反, arguments 反映了調用時提供的參數 :
function func(a = 55) { arguments[0] = 99; // 提供了默認參數,更新 arguments[0] 不會更新 a console.log(a); } func(10); // 10
並且
function func(a = 55) { a = 99; // 提供了默認參數,更新 a 不會更新 arguments[0] console.log(arguments[0]); } func(10); // 10
並且
function func(a = 55) { console.log(arguments[0]); } func(); // undefined //上面函數調用的時候沒有傳遞參數,所有 arguments[0] 值為 undefined