0


JavaScript(8):即时函数

  在JavaScript中定义一个函数后,声明一个函数并马上执行(调用)这个函数,这样的函数就是立即执行函数(Immediately-Invoked Function Expression 即IIFE),也称为即时函数(Immediately Function)。
  典型样式:

(function(形参){
//执行语句
//......
})(实参)

  也可以是:

(function (形参) {
//执行语句
//......
}(实参))

  推荐是第一种的写法,因为清楚明了,不容易产生歧义。
  有的习惯性在前面加;,比如;(function(){})();,这个是为了避免错误的习惯性写法(前面的语句最后没有加;)。
  如果在函数内没有对外变量的引用,也即没有闭包存在,那么这个函数执行完就作为垃圾回收了。
  多数情况下,我们应用都是没有实参和形参的。
  这里有一些的例子:

    (function func(){ console.log('B')})();//输出B
    console.log(!!function func(){ return 'C'; }());//输出true
    console.log(!(function(){ return true})());//输出false
    console.log(1 + function func(){ return 1; }());//输出2
    -(function func(){ console.log('D');})();//输出D

  在JavaScript语言当中要了解立即执行函数,先了解()的作用。
()可以是求值。
  那么圆括号里面的就是表达式。
  比如,可以写:
  a=(1+2);
  console.log(a);//输出3
  但是写成a=(1+2;)则报错,因为括号里面的是语句不是表达式。
  又例如:
  function a(){console.log('1')}();
  这个是报错的,因为JavaScript解释器遇到以function开头的都会以语句来解释。
  (function a(){console.log('1')}());
  这个则可以正确输出,因为以()包裹,则JavaScript解释器会认为里面的是可以执行的表达式。
()也可以是执行操作符。
  我的理解就是{}与执行()一一对应,想着是剥洋葱,{}就是封一层洋葱皮,而()则是剥一层洋葱皮。

    var K=function a(){
        return function b(){
            return function c(){
                return function d(){
                    return 'JavaScript';
                }
            }
        }
    };
    
    console.log(K()()()());    //输出JavaScript

  在JavaScript语言当中,()也是一个很神奇的存在,试看下面的代码,只是()的位置不一样导致结果也是不一样的。

    var a=(  function(){
        var count=0;
        return function (){
                count=count+1;
                return count;
        }
    })();
    
    console.log(typeof a);    //输出function
    console.log(a());//输出1
    console.log(a());//输出2
    console.log(a());//输出3

  上面的这个例子利用结合闭包来实现特定的效果。
  下面只是改变()的位置:

    var a=(  function(){
        var count=0;
        return function (){
                count=count+1;
                return count;
        }
    })()();
    
    console.log(typeof a);//输出number
    console.log(a);//输出1
    console.log(a);//输出1
    console.log(a);//输出1

  又或者写成下面的样式:

    var a=(  function(){
        var count=0;
        return function (){
                count=count+1;
                return count;
        }
    });
    
    console.log(typeof a);//输出function
    console.log(a()());//输出1
    console.log(a()());//输出1
    console.log(a()());//输出1

  下面是一个简单的计数功能的例子。

;(function (){
    var count=0;
    function add(){//增加计数
        count=count+1;
        return count;
    }
    function reduce(){//减少计数
        count=count-1;
        return count;
    }
    window.JS=function(){ return { add:add,reduce:reduce } }
}
)();
console.log(window.JS().add());//输出1
console.log(window.JS().add());//输出2
console.log(window.JS().add());//输出3

console.log(window.JS().reduce());//输出2
console.log(window.JS().reduce());//输出1

  下面是一道面试题,也是即时函数与闭包结合比较典型的试题:

    for(var i=0;i<5;i++){
        setTimeout( function(){
            i=i+1;
            console.log(i);
        },5000);
    };
  console.log('i:'+i);

  上面的代码段输出是什么?
  setTimeout(表达式,延时时间),意思是在载入后,在延迟时间后执行一次表达式。
  setInterval(表达式,交互时间),意思是在载入后,每隔交互时间就执行一次表达式。
  实际输出:

  如果要输出1、2、3、4、5,则应该改写代码:

    for(var i=0;i<5;i++){
        (function(x){
            setTimeout( function(){
                x=x+1;
                console.log(x);
            },5000)            
        })(i);
    }
    console.log('i:'+i);

  实际输出:

  在实际的应用中,我们常见即时函数的应用,比如事件挂载与绑定、初始化应用等等,即时函数经常与闭包联系在一起使用,比如在变量声明与引用、模块化开发等方面。


本文转载自: https://blog.csdn.net/dawn0718/article/details/122786205
版权归原作者 dawn 所有, 如有侵权,请联系我们删除。

“JavaScript(8):即时函数”的评论:

还没有评论