美文网首页JavaScript 进阶营
JavaScript学习之路-闭包

JavaScript学习之路-闭包

作者: LeoZzz | 来源:发表于2017-11-07 13:11 被阅读106次

    一、闭包?

    闭包一词想必iOS开发的童鞋指定很熟悉,Objective-C上的闭包叫Block,Swift上就叫闭包。如今JS上也出现了这个词语。请开始我的表演。

    二、对比OC/Swift

    OC:
     void (^aBlock)( void ) = ^( void ){
        
            };
    aBlock();//调用闭包
    

    熟悉C语言的是不是发现和C指针函数类似

    int sum (int x, int y) {
    return x+ y;
    }
    // 定义函数
    int (*p)(int, int) = sum;
    NSLog(@"%ld", p(2, 5));
    
    // 函数指针类型: int (*)(int, int);
    // 函数指针变量: p;
    // 函数指针的值: sum
    
    Block:
     block类型: int(^)(int, int)  
     block变量: block
     block值: ^(int x, int y){ 
      return x + y ;
    };
    
    swift上的闭包一般表达形式:
    { (parameters) -> returnType in
          statements
    }
    
    

    swift上的闭包 有很多简写的方法。

     // 作为变量
        var closureName: (parameterTypes) -> (returnType)
    
        // 作为可选类型的变量
        var closureName: ((parameterTypes) -> (returnType))?
    
        // 做为一个别名
        typealias closureType = (parameterTypes) -> (returnType)
    
        // 作为函数的参数
        func({(parameterTypes) -> (returnType) in statements})
    
        // 作为函数的参数
        array.sort({ (item1: Int, item2: Int) -> Bool in return item1 < item2 })
    
        // 作为函数的参数 - 隐含参数类型
        array.sort({ (item1, item2) -> Bool in return item1 < item2 })
    
        // 作为函数的参数 - 隐含返回类型
        array.sort({ (item1, item2) in return item1 < item2 })
    
        // 作为函数的参数 - 尾随闭包
        array.sort { (item1, item2) in return item1 < item2 }
    
        // 作为函数的参数 - 通过数字表示参数
        //内联闭包可以省略参数名直接用参数顺序$0,$1,$2调用.
        array.sort { return $0 < $1 }
    
        // 作为函数的参数 - 尾随闭包且隐含返回类型
        array.sort { $0 < $1 }
    
        // 作为函数的参数 - 引用已存在的函数
        array.sort(<)
    

    其中的尾随闭包

       // 以下是不使用尾随闭包进行函数调用
        someFunc({
            // 闭包主体部分
        })
      var reversed = sorted(["c","a","d","b"], { $0 > $1 })  
    
        // 以下是使用尾随闭包进行函数调用
        someFunc() {
          // 闭包主体部分
        }
    var reversed = sorted(["c","a","d","b"]) { $0 > $1 }
    

    三、JS闭包

    JS闭包和OC.Swift 是有区别的,JS上的闭包 在我的理解就是子级函数可以调用父级函数的变量。官方点的话就是:

    闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

    这里我找了俩个比较好的代码例子来给大家解释下:

    1. 例子一
    var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
            return this.name;
          };
        }
      };
      alert(object.getNameFunc()());
    

    在这个代码中,我们知道,JS上this默认的对象是widow,this就是指向函数执行时的当前对象。object.getNameFunc()() 是调用了函数。而rerun后的函数是 一个匿名函数 ,其实就是组成了一个闭包。而return 返回了this.name 并没有调用此匿名函数,所以this 指向widow对象的 所以alert提示的是 The Widnow
    也就是函数没有被自身的对象调用时, this 的值就会变成全局对象。

    1. 例子二
    var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          var that = this;
          return function(){
            return that.name;
          };
        }
      };
      alert(object.getNameFunc()());
    

    其实也是一个闭包,外层函数内 this 赋值给that ,that是该函数的局部变量,内部函数访问了that,形成闭包。所以调用的object.getNameFunc()() 的时候 是返回的 object.name:"My Object";

    四、总结

    闭包其实就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会增加内存消耗。或者说闭包就是子函数可以使用父函数的局部变量,还有父函数的参数。Javascript中的闭包是一个很重要的概念,希望童鞋们多看下经典代码,来熟练它的使用。

    相关文章

      网友评论

        本文标题:JavaScript学习之路-闭包

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