1. 程式人生 > >arguments物件詳解

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