簡析JavaScript中的Function類型(四)——函數的內部屬性

函數的內部屬性主要有三個:arguments, this, caller。其中this簡析JavaScript中的this關鍵字中探討的已經比較清楚了,這裏來講下argumentscallerjavascript

1. arguments

看下面的代碼:java

function sayHello(){
  console.log(arguments[0], arguments[1], arguments[2]);
}
sayHello('Bob', 'Jack', 'Rose');// Bob Jack Rose

如代碼所示,聲明sayHello時沒有顯式地聲明參數,可是在函數內部依然能夠經過arguments訪問傳遞給函數的參數。arguments是一個類數組對象,包含着傳入函數中的全部參數。數組

arguments除了能夠保存參數之外,它還有一個名叫callee的屬性,該屬性指向包含arguments的函數,以下代碼所示:函數

function sayHello(){
  console.log(arguments.callee);
}
sayHello();
/*
控制檯輸出:
ƒ sayHello(){
      console.log(arguments.callee);
    }
*/

那麼將函數的引用保存在arguments.callee中有什麼用處呢?下面是一個使用示例:this

//階乘函數
function factorial(num){
  if(num <= 1){
    return 1;
  }else{
    return num * factorial(num - 1);
  }
}
console.log(factorial(4));//24

這種寫法在函數有名字,並且名字之後也不會變的狀況下是沒有問題的。可是函數的執行與函數名factorial牢牢耦合在了一塊兒,當函數名發生變化時,調用就出現了問題:.net

var trueFactorial = factorial;
factorial = null;
console.log(trueFactorial(4));//Uncaught TypeError: factorial is not a function

使用arguments.callee能夠達到解耦的目的:code

function factorial(num){
  if(num <= 1){
    return 1;
  }else{
    return num * arguments.callee(num - 1);
  }
}

var trueFactorial = factorial;
factorial = null;
console.log(trueFactorial(4));// 24

如代碼所示,不管未來函數名如何變化,始終都能保證正確的執行結果。對象

2. caller

從字面意思理解,爲調用者。這個屬性保存着當前函數的調用函數,若是是在全局做用域中調用,它的值爲null。來看下面的例子:blog

function inner(){
  console.log(inner.caller);
}

function outer(){
  inner();
}

inner();// null
outer();// 結果以下:
/*
ƒ outer(){
      inner();
    }
*/

如代碼所示,在全局做用域中調用時結果爲null,在outer中調用時結果爲outer。一樣,爲了解耦合,也能夠將inner改寫以下:ip

function inner(){
  console.log(arguments.callee.caller);
}

須要注意的是嚴格模式是不支持argumentscaller屬性的。

相關文章
相關標籤/搜索