arguments物件詳解
在javascript中,函式是沒有過載這一項的,所謂的過載,一個函式可以有多個,就是引數的個數和形式不同所以引用的功能不同,而js不存在函式過載,不管傳不傳引數,函式裡面是否引用,關係都不大,一個函式對應一個功能,但是函式可以模擬函式過載,所以有一個Arguments物件。
定義
arguments是一個對應於傳遞給函式的引數的類陣列
物件。
類陣列:是陣列的形式,有length,但不具有陣列的一切方法
。
描述
arguments物件是所有(非箭頭)函式中都可用的區域性變數。你可以使用arguments物件在函式中引用函式的引數。此物件包含傳遞給函式的每個引數,第一個引數在索引0處。
箭頭函式沒有arguments物件
arguments是函式中必有的物件,用來讀取呼叫該函式的引數
function foo(){
console.log(arguments[0]) // 1
console.log(arguments[1]) // 2
console.log(arguments[2]) // 3
}
foo(1,2,3)
arguments物件不是陣列,但可以通過其他方式轉化為陣列,進而使用陣列的方法。
var args = Array.prototype.slice.call(arguments)
var args = [].slice.call(arguments);
var args = Array.from(arguments)
var args = [...arguments]
function foo() {
var f = Array.prototype.slice.call(arguments);
// var f = [].slice.call(arguments);
// var f = Array.from(arguments);
// var f = [...arguments];
console.log(f) // [1,2,3]
console.log(f instanceof Array) // true
}
foo(1, 2, 3)
屬性
arguments既然是個物件,也有它的自帶的屬性。
- length 長度,本次函式呼叫時傳入函式的實引數量.
- 表示的是實際上向函式傳入了多少個引數,這個數字可以比形引數量大,也可以比形引數量小
- 形參:全稱“形參變數”,只有在被呼叫時才分配記憶體單元,在呼叫結束時,即刻釋放所分配的記憶體單元。因此,形參只在函式內部有效。函式呼叫結束返回主呼叫函式後則不能再使用該形參變數。
- 實參:全稱為"實際引數"是在呼叫時傳遞給函式的引數. 實參可以是常量、變數、表示式、函式等, 無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值, 以便把這些值傳送給形參。 因此應預先用賦值,輸入等辦法使實參獲得確定值。
形參就是函式宣告的引數,實參是函式呼叫的引數
function foo(a,b){} // a,b代表形參 foo(1,2) // 1,2代表實參
- callee 當前正在執行的函式
- 可以用於引用該函式的函式體內當前正在執行的函式(類似於遞迴)
- es5之後廢棄,但不代表不使用這個callee了
- callee可以使用在匿名遞迴函式中。
- 匿名函式 (通過 函式表示式 或者 函式構造器 建立) 沒有名稱。因此如果沒有可訪問的變數指向該函式,唯一能引用它的方式就是通過 arguments.callee。
function create() { return function (n) { if (n <= 1) return 1; return n * arguments.callee(n - 1); }; } var result = create()(5); console.log(result) // returns 120 (5 * 4 * 3 * 2 * 1)
- 但不提倡使用callee來遞迴,最好形成有名函式,進而使用函式名遞迴。
function create() { return function multiply(n) { if (n <= 1) return 1; return n * multiply(n - 1); }; } var result = create()(5); console.log(result) // returns 120 (5 * 4 * 3 * 2 * 1)
- caller 指向呼叫當前函式的函式
- 原先用在函式執行的時候呼叫自身
- 已廢棄,不能用
- arguments[@@iterator] 返回一個新的Array迭代器物件,該物件包含引數中每個索引的值。
- 這個意思就是可以呼叫for-of迴圈 - -!
function add(){ for(var i of arguments){ console.log(i) //1 2 3 4 5 6 } } add(1,2,3,4,5,6)
特殊點
當arguments遇到剩餘函式,解構賦值和預設引數的情況:- 在嚴格模式下,剩餘引數、預設引數和解構賦值引數的存在不會改變 arguments物件的行為,
"use strict" function func(...a) { a[0] = 11 console.log(arguments); } func(1,2,3,4,5); // [1,2,3,4,5] function func1(a=4) { console.log(arguments); } func1(1); // [1]
- 當非嚴格模式中的函式沒有包含剩餘引數、預設引數和解構賦值,那麼arguments物件中的值會跟蹤引數的值(反之亦然)
function func(a) { arguments[0] = 99; // 更新了arguments[0] 同樣更新了a console.log(a); } func(10); // 99 function func1(a) { a = 99; // 更新了a 同樣更新了arguments[0] console.log(arguments[0]); } func1(10); // 99
- 當非嚴格模式中的函式有包含剩餘引數、預設引數和解構賦值,那麼arguments物件中的值不會跟蹤引數的值(反之亦然)
function func(a = 55) { arguments[0] = 99; // 更新了 arguments[0] 但沒更新 a console.log(a); } func(10); // 10 function func1(a = 55) { a = 99; // 更新了 a 但沒更新arguments[0] console.log(arguments[0]); } func1(10); // 10 function func2(a = 55) { console.log(arguments[0]); } func2(); // undefined
總結
前段時間看到arguments物件,不是很懂,所以抽空學習了一下。es6箭頭函式的出現,arguments物件相對來說少用了,因為箭頭函式沒有arguments物件。再加上有一些屬性都被遺棄。但是不能不學,所有的知識都是從底層創建出來的,瞭解底層知識是有好處的。
如果此文有什麼不對的地方,歡迎評論私信,大家一起進步。我把我總結的知識點放到GitHub了,如果滿意,給個star。
參考文獻
MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments