4

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

这段代码创建了一个自定义函数:

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

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

var prank = scareMe; 

令人困惑的部分是,当我打电话给恶作剧时,它应该更新 scareMe,当我打电话给它时,它应该提醒“双重嘘声”,不是吗?

但结果是

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

如果我检查了 scareMe 函数,它确实被重新定义了。

scareMe(); // Double boo!

恶作剧只是对scareMe的引用,为什么有区别?

4

3 回答 3

6

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

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

看这个:

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

这没有什么神奇之处,它会重新分配最近的scareMe变量,这恰好是全局变量。它不做任何其他事情。

于 2012-08-10T09:23:04.303 回答
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!'

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

于 2012-08-14T07:27:05.403 回答
2

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

如果你之前调用scareMe();prank();,它会提醒Boo!并分配一个新的功能scareMe,所以下次你打电话时scareMe();,它会提醒Double boo!

在你的情况下,它是一样的,你打电话prank();,它会提醒Boo!并分配一个新功能给scareMe,所以在那之后,如果你打电话scareMe();,它会提醒Double boo!

于 2012-08-10T09:38:58.163 回答