JavaScript 进阶营

JavaScript学习之路-闭包

2017-11-07  本文已影响106人  LeoZzz

一、闭包?

闭包一词想必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中的闭包是一个很重要的概念,希望童鞋们多看下经典代码,来熟练它的使用。

上一篇下一篇

猜你喜欢

热点阅读