为什么自定义函数引用指向旧函数

时间:2012-08-10 09:15:30

标签: javascript

我在“javascript设计模式”中找到了这个例子,并与下面代码的行为相混淆

此代码创建自定义函数:

var scareMe = function () {
   alert("Boo!");
   scareMe = function () {
     alert("Double boo!");
  };
};

现在我们将它引用到另一个变量

var prank = scareMe; 
困惑的部分是当我打电话给恶作剧时它应该更新scareMe,当我回电话时它应该警告“Double boo”不是吗?

但结果是

prank(); // "Boo!"
prank(); // "Boo!"

如果我检查scareMe功能确实已经重新定义了。

scareMe(); // Double boo!
恶作剧只是对scareMe的引用,而不是为什么会有差异?

3 个答案:

答案 0 :(得分:6)

prank不是对scareMe的引用(这是javascript中的不可能),它是对函数对象的引用。 2个变量独立地指代相同的函数。

该函数显式覆盖scareMe指向的任何内容。它不会以任何方式影响prank

看看这个:

scareMe = function() {
    alert("Double boo!");
};

这没有任何魔力,它将重新分配最接近的scareMe变量,这恰好是全局变量。它没有做任何其他事情。

答案 1 :(得分:5)

prank指向原始函数,而不是scareMe

看看这个例子:

var scareMe = 1;
var prank = scareMe;

scareMe = 2;

您不希望更改scareMe会更改prank,对吗?这与功能完全相同。

var scareMe = function() { alert( 'Boo' ); };
var prank = scareMe;

scareMe = function() { alert( 'Double boo!' ); };

在这方面,整数和函数之间没有区别 - prank保持不变,即使scareMe发生变化也是如此。从另一个函数内部更改scareMe并不会改变这一事实。

混淆可能来自于如何使用对象。改变原始函数并不常见,因为你可能会更改对象的属性。

var scareMe = { message: 'Boo' };
var prank = scareMe;

scareMe.message = 'Double boo!';

alert( prank.message );  // alerts 'Double boo!'

这不是您在原始示例中使用函数所做的事情。将变量更改为指向完全不同的函数不会更改其他变量中的函数引用。

答案 2 :(得分:2)

scareMe();的结果取决于执行顺序。

如果您在scareMe();之前致电prank();,则会提醒Boo!并为scareMe分配新功能,以便您下次拨打scareMe();时,它会提醒Double boo!

在您的情况下,它是相同的,您致电prank();,它会提醒Boo!并为scareMe分配一个新功能,所以在此之后,如果您致电{{1} }},它会提醒scareMe();