美文网首页
JS系列(五):函数作用域

JS系列(五):函数作用域

作者: 青叶小小 | 来源:发表于2021-04-02 10:44 被阅读0次

    和其它语言一样,函数或者说方法,都有自己的作用域。通过不同的代码块管理,来实现变量、函数、功能等隐藏,最终目标:高聚敛、低耦合

    var a = 1;
    function foo() {
        var a = 2;
        console.log(a); // 2
    }
    foo();
    console.log(a); // 1
    

    我们通过foo函数,将内部变量隐藏起来,看似很好,但是我们确污染了全局对象,因为foo方法被加入到全局对象中,而且我们还需要多写一行代码foo()来主动执行;

    那有没有不污染全局对象,又能直接执行的方式呢?
    当然有咯,而且这种方式还有个名称:IIFE(Immediately Invoked Function Expression)【立即执行函数表达式】

     var a = 1;
     (function foo(){
         var a = 2;
         console.log(a); // 2
     })();
     console.log(a); // 1
     console.log(window.foo) // undefined
    

    IIFE这种方式满足了我们所有的需求。这就是早期jQuery的实现方式!!!第一个()所包裹的是一个函数表达式,因此,我们在后面添加括号也就是 第二个()时,该函数表达式就立即执行了。

    上面的IIFE函数名可以省略(function (){...})();但是,好的做法是给定一个函数名。另外,我们也可以给IIFE传递参数:

     var a = 1;
     (function foo(global){
         var a = 2;
         console.log(a, global.a); // 2 1
     })(window);
     console.log(a); // 1
    

    另外,IIFE也可以避免一些问题:

     var undefined = true; // 大坑!
     (function foo(undefined){
         var a;
         if (a === undefined) {
             console.log("undefined is safe here");
         }
     })();
    

    还有一种写法,目前也是被广泛使用的,UMD(Universal Module Definition)

    (function IIFE(def) { 
        def(window);
    })(function def(global) {
        var a = 3;
        console.log(a, global.a); // 3 2
    });
    

    函数表达式def定义在片段的第二部分,然后当作参数(这个参数也叫作 def)被传递进 IIFE 函数定义的第一部分中。最后,参数 def(也就是传递进去的函数)被调用,并将window传入当作global参数的值。

    相关文章

      网友评论

          本文标题:JS系列(五):函数作用域

          本文链接:https://www.haomeiwen.com/subject/uemfkltx.html