使用函数声明时的自定义函数(也称为惰性函数定义)

时间:2013-09-30 01:57:04

标签: javascript function

在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!

问题

  1. 他们之间有什么区别?
  2. 在第二种情况下,为什么输出不是“Double Boo!”,而是“Boo!”

3 个答案:

答案 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 变量,该变量会遮挡外部变量。