zoukankan      html  css  js  c++  java
  • 函数的闭包

    一、函数声明、函数表达式、匿名函数

    1、函数声明

    语法格式:function fnName () {…};
    定义:使用function关键字声明一个函数,再指定一个函数名。

    2、函数表达式

    语法格式:var fnName = function () {…};
    定义:使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量。

    3、匿名函数

    语法格式:function () {…}; 
    定义:使用function关键字声明一个函数,但未给函数命名,匿名函数属于函数表达式。
    作用:赋予一个变量则创建函数;赋予一个事件则成为事件处理程序;赋予一个事件则创建闭包。

    二、加括号后

    //函数声明后面加括号,不会报错,但是javascript引擎只解析函数声明,会忽略后面的括号,函数声明不会被调用。
    function fnName(){
        alert('Hello World');
    }();
    //函数表达式后面加括号,当javascript引擎解析到此处时,能立即调用该函数。
    var fnName=function(){
        alert('Hello World');
    }();
    //匿名函数后面加括号,显示语法报错:要求需要一个函数名。虽然匿名函数属于函数表达式,但是未进行赋值操作,所以javascript引擎将开头的function关键字当做函数声明。
    function(){
        console.log('Hello World');    
    }();

    三、函数的闭包、命名空间

    函数的闭包(closure)可以让匿名函数立即被执行,这种闭包的优势是:

    1、减少了全局变量的个数,可以有效减少命名冲突。原因是包在里面的变量对于外面来说是不可见的,他们的作用域局限在匿名函数的函数体内。

    2、这种方式可以保存闭包外面的变量的状态。

    多人合作一个项目时,你在全局或局部作用域中声明了一些变量,这些变量可能被其他人的同名变量覆盖掉,根据javascript函数作用域链的特性,可以使用这种技术模仿一个私有作用域,用匿名函数作为一个“容器”,“容器内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

    Jquery使用的就是这种方法,将Jquery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用Jquery代码时,可以保护Jquery内部变量。

    四、javascript立即执行函数有哪些方法?

    要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明。

    1、(function(){…})()

    相当于先定义 function xx(){},后调用 xx()。是利用匿名函数和闭包来执行…里面的代码,同时所有的定义比如变量的作用域都在闭包里,不会污染到外部命名空间。

    function(){…}是一个匿名函数,包裹着function(){…}的()表示拥有最高级的优先执行权。后面的()表示执行完function(){…}后,立即调用function(){…}。

    (function(a){
        console.log(a);   //firebug输出123,使用()运算符
    })(123);

    2、(function (){…} ())

    (function(a){
        console.log(a);   //firebug输出1234,使用()运算符
    }(1234));

    3、其他方法

    !function(a){
        console.log(a);   //firebug输出12345,使用!运算符
    }(12345);
    
    +function(a){
        console.log(a);   //firebug输出123456,使用+运算符
    }(123456);
    
    -function(a){
        console.log(a);   //firebug输出1234567,使用-运算符
    }(1234567);
    
    var fn=function(a){
        console.log(a);   //firebug输出12345678,使用=运算符
    }(12345678)

    ()、!、+、-、=等运算符告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。加括号是最安全的做法,因为!、+、-、=等运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。

    五、实例应用

    function fn() {
        for(var i=0 ; i<2; i++) {
            var backup = i;
            setTimeout(function() {
                alert(backup);
            }, 2000);
        }
    }
    fn();

    上面代码的for循环一共两次,我们本来的目的是每隔两秒钟把每一次循环的索引i输出,我们期待它应该输出0和1,但是实际输出结果两次都是1。

    使用了闭包之后,我们可以把循环中每一次i值的状态都保存下来。

    function fn() {
        for(var i=0 ; i<2; i++) {
        (function(){
            var backup = i;
            setTimeout(function() {
                alert(backup);
            }, 2000);
        })();
        }
    }
    fn();

    这次我们得到了正确的结果0和1。

  • 相关阅读:
    eletron打包
    助力ASP.NET Core 2.1开发!Layx 企业级弹窗插件发布!
    springcloud 入门 3 (服务之间的调用)
    springcloud 入门 2 (Enreka的服务和注册)
    springcloud 入门 1 (浅谈版本关系)
    springboot 学习之路 18(webflux详细介绍(2))
    springboot 学习之路 17(webflux 入门 (1))
    springboot 学习之路 15(集成shiro)
    Mongodb的入门(6)副本集
    Mongodb的入门(4)mongodb3.6的索引
  • 原文地址:https://www.cnblogs.com/camille666/p/function_closure.html
Copyright © 2011-2022 走看看