• js闭包原理和用法


    对闭包的简单解释

    全局变量生存周期是永久,局部变量生存周期随着函数的调用介绍而销毁。闭包就是 在函数中定义且成为该函数内部返回的函数的自由变量 的变量,该变量不会随着外部函数调用结束而销毁。 (注:不光是变量,函数内声明的函数也可以形成闭包)

    当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包。

    function foo(){
        let a = 1;
        return function sum(){
                console.log(a);
               return a++;
        };
    }
    let test = foo();             //闭包的产生:在执行foo函数时将返回的函数赋值给了一个变量,让foo中变量a可供返回的函数使用而不被销毁。
    test();  //1
    test();  //2
    test();  //3
    // foo函数中的变量a在foo调用结束后依旧保存了下来,这就是闭包。
    

    函数也可以成为闭包

    let bibao = function(){
    	let a = 1;
    	function test(){
    		a++;
    		console.log('函数依旧可以形成闭包'+a);
    	};
    	return function(){
    		test();
    	}
    }
    let fun = bibao();
    fun();//函数依旧可以形成闭包2
    fun();//函数依旧可以形成闭包3
    fun();//函数依旧可以形成闭包4
    

    for循环闭包

    for (var i=1; i<=5; i++) {
        (function(j) {
            setTimeout( function timer() {
                console.log( j );
            }, j*1000 );
        })( i );
    }
    

    闭包的应用一 模块

    function CoolModule() {
        var something = "cool";
        var another = [1, 2, 3];
        function doSomething() {
            console.log( something );
        }
        function doAnother() {
            console.log( another.join( " ! " ) );
        }
        return {
            doSomething: doSomething,
            doAnother: doAnother
        };
    }
    var foo = CoolModule();
    foo.doSomething(); // cool
    foo.doAnother(); // 1 ! 2 ! 3
    
    

    模块中闭包形成分析:
    首先,CoolModule() 只是一个函数,必须要通过调用它来创建一个模块实例。如果不执行外部函数,内部作用域和闭包都无法被创建。
    其次,CoolModule() 返回一个用对象字面量语法 { key: value, ... } 来表示的对象。这个返回的对象中含有对内部函数而不是内部数据变量的引用。我们保持内部数据变量是隐藏且私有的状态。可以将这个对象类型的返回值看作本质上是模块的公共 API。

    闭包的应用二 封装变量

    闭包可以帮助把一些不需要暴露在全局的变量封装成“私有变量”。例如使用js实现栈、队列等数据结构,需要将内部是数组进行私有化封装。

    var mult = (function(){ 
         var cache = {}; 
        return function(){ 
             var args = Array.prototype.join.call( arguments, ',' ); 
             if ( args in cache ){ 
                 return cache[ args ]; 
             } 
             var a = 1; 
             for ( var i = 0, l = arguments.length; i < l; i++ ){ 
                 a = a * arguments[i]; 
             } 
             return cache[ args ] = a; 
         } 
    })(); 
    alert ( mult( 1,2,3 ) ); // 输出:6 
    alert ( mult( 1,2,3 ) ); // 输出:6 
    

    闭包的应用三 延续局部变量的寿命

    img 对象经常用于进行数据上报,如下所示:

    var report = function( src ){ 
     var img = new Image(); 
     img.src = src; 
    }; 
    report( 'http://xxx.com/getUserInfo' ); 
    

    但是通过查询后台的记录我们得知,因为一些低版本浏览器的实现存在 bug,在这些浏览器下使用 report 函数进行数据上报会丢失 30%左右的数据,也就是说,report 函数并不是每一次都成功发起了 HTTP 请求。丢失数据的原因是 img 是 report 函数中的局部变量,当 report 函数的调用结束后,img 局部变量随即被销毁,而此时或许还没来得及发出 HTTP 请求,所以此次请求就会丢失掉。现在我们把 img 变量用闭包封闭起来,便能解决请求丢失的问题

     var report = (function(){ 
         var imgs = []; 
         return function( src ){ 
             var img = new Image(); 
             imgs.push( img ); 
             img.src = src; 
         } 
    })(); 
    
  • 相关阅读:
    大搬家--百度之星 (递推)
    Scrambled Polygon--poj2007(极角排序模板)
    Space Ant--poj1696(极角排序)
    A. Link/Cut Tree--cf614A ()
    Ultra-QuickSort--POJ2299(归并排序求逆序数对)
    An Easy Problem?!--
    C. The Two Routes---cf602C(Dij)
    java 中jar的使用
    两种方法解决tomcat的 Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]
    Ajax(6) Ajax向servlet请求数据库操作 并显示到当前页面 这个未经测试
  • 原文地址:https://www.cnblogs.com/honkerzh/p/10572801.html
Copyright © 2020-2023  润新知