Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用函数声明时的自定义函数(也称为惰性函数定义)_Javascript_Function - Fatal编程技术网

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

Javascript 使用函数声明时的自定义函数(也称为惰性函数定义),javascript,function,Javascript,Function,在Stoyan Stefanov的《JavaScript模式》一书中,有一部分是关于自定义函数的 var scareMe = function(){ console.log("Boo!"); scareMe = function(){ console.log("Double Boo!"); } } scareMe();//==>Boo! scareMe();//==>Double Boo! 正如我所预料的那样。但我修改scareMe函数如

在Stoyan Stefanov的《JavaScript模式》一书中,有一部分是关于自定义函数的

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!
问题

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

  • 调用第一个
    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!
    

    除提升和调试能力外,您可以考虑:

    function f(/* ... */) { /* ... */ }
    
    相当于:

    var f = function(/* ... */) { /* ... */ };
    
    如果我们将您的第二个代码示例转换为使用第二个表单,我们将得到:

    var scareMe = function() {
        console.log("Boo!");
        var scareMe = function() {
            console.log("Double bool!");
        };
    };
    

    请注意,这与您的第一个代码片段不同;内部函数定义上有一个
    var
    。使用内部的
    var
    ,它将创建一个名为
    scareMe
    的新变量,该变量将外部变量隐藏起来。

    在您的第一个方法中,scareMe是一个全局变量(在您的上下文中)。在“双boo”中,更改该全局变量的值,使其工作。 在第二种方法中,内部scareMe是一个局部变量,它不会改变全局变量的值。
    这是关于变量作用域的。

    这种模式令人惊讶。除了迷惑,还有什么实际用途吗???@游戏炼金术士:是的。有时我有一个功能去做一些我只想做一次的事情;比如说初始化。我可以这样定义这个函数:
    functioninit(){init=function(){};/*…*/}init
    ,而不是实际捕获对原始函数的引用,它将只初始化一次。这可以用一个布尔变量来完成,但这样你就少了一个要跟踪的变量。例如,用setInterval替换rAF可以是:requestAnimationFrame=function(cb){requestAnimationFrame=function(){};returnsetInterval(cb,16);}。有点神秘,但很优雅。我的朋友谷歌说,你打错了名字:它是斯托扬·斯特凡诺夫。@gamealchest:在这本书中,作者也用这个模式创建了单态模式。函数Singleton(){instance=this;Singleton=function(){return instance};}。然后,当您创建两个实例时,它们是相同的。var s1=新单例();var s2=新单例();console.log(s1==s2);我不认为你所说的提升实际上是提升。我想你的意思是说他们在修改一个封闭变量。@user2782160:你的答案其实很不一样。我解释你说你不能覆盖一个函数,这是错误的。你当然可以;只是在第二个代码段中,它们没有覆盖函数;他们在跟踪它。@icktoofay不是我真正的意思是实际的
    scareMe
    函数在全局范围内,在第一个示例中,您定义了另一个不带
    var
    的函数,它被提升到全局scrope,这意味着它只是覆盖了第一个scareMe的定义。看看我答案中的第一个例子,它是如何变化的。@PSL:我明白你在说什么,但我认为你的术语弄错了。提升是JavaScript的行为方式,就像所有函数定义和变量声明都移动到范围的开头一样。这不是你所说的提升;你实际上想说的是,它正在修改它关闭的外部作用域中的变量,这与提升不同。@icktoofay啊,是的,对,这就是我的意思,它只是因为缺少作用域而修改自己的行为。在第二个例子中,我不认为内部的scareMe会影响外部的scareMe,如果是这样,输出将是“Double boo!”,事实上,输出是“boo!”。我认为Teddy是对的。@jason:Teddy是对的,但是当我说shadowing时,我的意思是你有两个同名的变量,最里面的一个隐藏了最外面的变量的定义;我并不是说外面的那个完全改变了,只是它被隐藏了。是的,我理解你稍后的意思,对不起:)