• javascript---闭包


    1. 闭包

        有权访问另一个函数作用域中变量的函数,常见创建闭包的方式是在一个函数内部创建另一个函数。

    2. 闭包原理

       先看看普通函数执行过程中,如何在作用域链查找变量的:

    1 function compare(val1, val2) {
    2    if(val1 < val2 ) {
    3        return -1;  
    4    }  else if (val1 > val2) {
    5        return 1;
    6    } else {
    7        return 0;  
    8    }
    9 }
    10 var result = compare(5,10);

      compare函数在执行过程中的作用域链:

        

      简单的闭包函数:

    1 function createComparesionFunction(propertyName) {
    2     return function(object1, object2) {
    3         var val1 = object1[propertyName];
    4         var val2 = object2[propertyName];
    5         if(val1 < val2) {
    6               return -1;
    7           } else if (val1 > val2) {
    8               return 1;
    9           } else {
    10               return 0;
    11           }
    12     }
    13 }
    14 var compareNames = createCompareFunction("name");
    15 var result = compareNames({name: 'frank', name: 'jack'});
    16 compareNames = null; (解除引用,释放内存)

    注意: 由于闭包会包含它的函数的作用域,因此比其他函数占用内存要多,所以只有在必要的时候再使用

    3. 闭包应用场景

       (1) 外部函数读取内部函数变量

     1 function f1() {
     2    var n =99;
     3    function f2() {
     4        alert(n);
     5    }
     6    return f2;
     7 }
     8 
     9 var result = f1();
    10 result();//99

       (2) 将变量一直保存到内存中

     1 function f1() {
     2   var n = 99;
     3   nAdd = function() {n +=1};
     4   function f2 () {
     5     alert(n);
     6   }  
     7   return f2;
     8 }
     9 
    10 var result = f1();
    11 result();//99
    12 nAdd();
    13 result();//100

      分析: result是f2闭包函数, 调用两次闭包函数,第一次输出是99,第二次输出是100. 可以看出局部变量并没有因为f1()函数执行之后,而从内存中清除掉,而是一直保存在内存中。原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

     4. 使用闭包注意事项

       (1). 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

       (2). 闭包在父函数外面,可以改变父函数内部的变量,如果将父函数作为对象,闭包作为公共方法,变量为私有属性,这是要注意不要随便改变父函数中的变量

  • 相关阅读:
    Count and Say leetcode
    Find Minimum in Rotated Sorted Array II leetcode
    Find Minimum in Rotated Sorted Array leetcode
    Search in Rotated Sorted Array II leetcode
    search in rotated sorted array leetcode
    Substring with Concatenation of All Words
    Subsets 子集系列问题 leetcode
    Sudoku Solver Backtracking
    Valid Sudoku leetcode
    《如何求解问题》-现代启发式方法
  • 原文地址:https://www.cnblogs.com/learning-skills/p/7645077.html
Copyright © 2020-2023  润新知