在Stoyan Stefanov的“JavaScript Patterns”一书中,有一部分是关于自我定义的功能。
var scareMe = function(){
console.log("Boo!");
scareMe = function(){
console.log("Double Boo!");
}
}
scareMe();//==>Boo!
scareMe();//==>Double Boo!
它按我的预期工作。但我将scareMe功能修改如下:
function scareMe(){
console.log("Boo!");
function scareMe(){
console.log("Double Boo!");
}
}
scareMe();//==>Boo!
scareMe();//==>Boo!
问题:
答案 0 :(得分:11)
调用时的第一个scareMe
函数通过在其中创建另一个函数scareMe
来覆盖自己的行为,它覆盖了较高范围内的函数,因此原始scareMe
的定义发生了变化,我已经看到如果您想在应用程序中首次设置并希望在设置后立即改变其行为,则会使用此方法。
如果您已定义:
var scareMe = function(){
console.log("Boo!");
var scareMe = function(){ //define it with var
console.log("Double boo!");
}
}
scareMe();//==>Boo!
scareMe();//==>Boo! //you will see the behavior as that of the second one.
一次性设置的一个实际实现:
var scareMe = function(){
console.log("Boo!");
//I have done my job now. I am no longer needed.
scareMe = undefined;
}
scareMe();//==>Boo!
scareMe();//==> oops error
第二种情况你正在创建一个名为scareMe
的新函数,其范围仅在函数内,它不会覆盖自身。
例如尝试这个:
function scareMe(){
console.log("Boo!");
function scareMe(){
console.log("Double bool!");
}
scareMe(); //Now this invokes the once defined inside the scope of this function itself.
}
scareMe();//==>Boo! and Double bool!
答案 1 :(得分:4)
在您的第一个approch中,scareMe是一个全局变量(在您的上下文中)。在“double boo”中,您可以更改该全局变量的值,因此它可以正常工作。 在第二个approch中,内部scareMe是一个局部变量,它不会改变全局变量的值。 所以它是关于变量范围的。
答案 2 :(得分:2)
除了提升和可调试性外,您可以考虑:
function f(/* ... */) { /* ... */ }
相当于:
var f = function(/* ... */) { /* ... */ };
如果我们将您的第二个代码示例翻译为使用第二个表单,我们会得到:
var scareMe = function() {
console.log("Boo!");
var scareMe = function() {
console.log("Double bool!");
};
};
请注意,不与您的第一个代码段相同;内部函数定义上有var
。使用内部var
,它会创建一个名为scareMe
的 new 变量,该变量会遮挡外部变量。