2012-03-02 62 views
4

在下面的JavaScript代码:混乱了在JavaScript中的功能与性能参考

function foo() { 
    foo.val = foo.val || 'no val'; 
    return 'foo has ' + foo.val; 
}; 
function bar() { 
    bar.val = bar.val || 'no val'; 
    return 'bar has ' + bar.val; 
}; 
var a = foo; 
foo.val = '1'; 
bar.val = '2'; 
a.val = '3'; 
foo = bar; 
'foo says "' + foo() + '", bar says "' + bar() + '", a says "' + a() +'"'; 

我期望是:

富说:“酒吧已2”,显示的是“棒有2" 个,一个说 “富有3个”

然而,从Firebug控制台在Firefox 10.0.2上运行时,我得到:

富说:“酒吧已2”,显示的是“酒吧有2个”,一个说“富已经2”

谁能向我解释事件的是那张幕后的顺序进行这是吗?为什么a保留绑定到原始foo函数(我所期望的),但保留bar的值为val

回答

4

这行代码后:

var a = foo; 

a指向相同的功能foo点。在

foo = bar; 

重新分配foo指向任何bar指。这不会更新a的参考 - 它仍然指向foo最初也指向的功能。

现在,当您运行a()时,将执行原始函数。它抓取foo(现在指向bar的引用)并获取其val属性。 barval的对象是2,所以这是返回的内容。

用文字解释有点难......图表会更容易理解吗?

+1

+1。这是令人困惑的解释,但我认为你做得比我做得更好。 – nnnnnn 2012-03-02 01:36:41

+0

不需要图表,这是一个很好的解释。我正在寻找一种方法来引用没有'arguments.callee'的函数,因为它在ES5严格模式下引发了一个TypeError。我想我必须小心,不要重新分配我的功能。 – beldaz 2012-03-02 01:42:43

4

foo()功能通过a()调用执行,它的代码表示,拿到foo.val的价值,那就是,无论fooval财产是指在那一刻。所以,你的a()功能,有效看起来是这样的:

function a() { 
    foo.val = foo.val || 'no val'; 
    return 'foo has ' + foo.val; 
}; 

foo在这一点上仅仅是bar参考。

+1

啊。我曾想过(希望)foo函数定义中对'foo.val'的调用会绑定到原始函数。谢谢你清理那个。 – beldaz 2012-03-02 01:35:51