一、闭包?
闭包一词想必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上的闭包 在我的理解就是子级函数可以调用父级函数的变量。官方点的话就是:
闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
这里我找了俩个比较好的代码例子来给大家解释下:
- 例子一
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 的值就会变成全局对象。
- 例子二
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中的闭包是一个很重要的概念,希望童鞋们多看下经典代码,来熟练它的使用。