2015-04-26

Javascript 的 callee 屬性

每個 function 裡都有個叫做 arguments 的隱藏版屬性,所謂隱藏版屬性就是不用定義或宣告,立即可用。

arguments 多半用來處理可變參數數量的情況。
function a(b, c) {
  return b + c;
}
console.log(a(2, 3)); // 5

function a() {
  var b = 0;
  for (var i=0; i<arguments.length; i++) { // 隱藏版屬性,憑空出現
    b += arguments[i];
  }
  return b;
}
console.log(a(2, 3)); // 5
console.log(a(2, 3, 4)); // 9
console.log(a(2, 3, 4, 5)); // 14
arguments 除了可以用來讀取傳入 function 的參數外,還有一個特別的屬性,就是 callee。

官方定義 callee:指向目前正在執行的 function 物件。
var f = function() {
  return arguments.callee === f;
};
console.log(f()); // true
callee 主要用於遞迴計算,尤其在匿名 function 裡執行遞迴呼叫時,callee 是唯一的方法 。

一般的遞迴作法。
function f(n) {
  if (n <= 1) {
    return 1;
  }
  return n * f(n - 1);
}
console.log(f(5)); // 120
在無名 function 裡,因為無名所以無法直接呼叫以進行遞迴,這時候就可以用 arguments.callee。
var f = function(n) {
  if (n <= 1) {
    return 1;
  }
  return n * arguments.callee(n - 1);
};
console.log(f(5));
但是無名 function 裡還是可以用變數名稱來進行遞迴。
var f = function(n) {
  if (n <= 1) {
    return 1;
  }
  return n * f(n - 1);
};
console.log(f(5));
真正需要 callee 的是匿名 function 的遞迴。
function f(n, callback) {
  return callback(n);
}

console.log(f(5, function(n){
  if (n <= 1) {
    return 1;
  }
  return n * arguments.callee(n - 1); // 沒有任何 function name 可以呼叫,唯有 arguments.callee
}));
但是在 ECMAScript 5 的 strict mode,callee 屬性在是禁止使用的。
---
---
---

沒有留言:

張貼留言