◆ 再帰で arguments.callee を呼び出すと this が呼び出し元の引数になってる
◆ bind(this) すると普通に使える
◆ デバッグに良さそうだけどなんかイヤ 

前記事の最後でちょっと書いた arguments.callee の this が変わる謎仕様ですが 実は便利なのかもしれません

こんな関数を定義します
function f(n, sum){
console.log(this)
return n === 0 ? sum : arguments.callee(n-1, sum + n)
}

実行すると
> f(10,0)
Window {...}
[10, 0]
[9, 10]
[8, 19]
[7, 27]
[6, 34]
[5, 40]
[4, 45]
[3, 49]
[2, 52]
[1, 54]
< 55
なんと 再帰の過程が見れます

呼び出し元の関数が受け取った引数が見れます
this がある関数じゃなくて this の呼び出し元のです
その証拠に [0, 55] はでてないですよね


この動きをするのは再帰呼び出ししてるときだけのようです
function f(){
console.log(this)
f1 = f
f2 = arguments.callee
}
function g(){f1(), f2()}

f()
// Window {...}
g(1,2,3)
// Window {...}
// Window {...}
arguments.callee がただの関数への参照じゃなくて特殊な関数に置き換わっているなら arguments.callee を取り出して 関数 g から呼び出しているので g(1,2,3) で表示される結果の 2 つめは呼び出し元 g の引数の [1,2,3] になってるはずです
ですが 普通に Window です

まぁそうなるだろうと思いましたけど 扱いづらい仕様ですね
デバッグには役立つでしょうけど やっぱり安全のために callee には毎回 bind するほうがいいと思います
this 使うつもり無くても 修正して this を使うようになるかもしれないですし

bind するとこうなります
function f(n, sum){
console.log(this)
return n === 0 ? sum : arguments.callee.bind(this)(n-1, sum + n)
}
f(10,0)
// Window {...}
// Window {...}
// Window {...}
// ... 略 ...
// Window {...}
// 55
1 つめの実行は本来の this でそのときの this を bind するのでプロパティだった場合も大丈夫です
var obj = {
sum: 0,
f: function(n){
console.log(this)
this.sum += n
return n === 0 ? this.sum : arguments.callee.bind(this)(n-1)
}
}
obj.f(10)
// Object {sum: 0}
// Object {sum: 10}
// Object {sum: 19}
// Object {sum: 27}
// Object {sum: 34}
// Object {sum: 40}
// Object {sum: 45}
// Object {sum: 49}
// Object {sum: 52}
// Object {sum: 54}
// Object {sum: 55}
// 55