闭包有人说是函数有人说是一个概念,其实表达的核心思想是一样的。比如:
说法一:
闭包函数:声明在一个函数中的函数,叫做闭包函数。
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
说法二:
简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。
MDN 上面这么说:闭包是一种特殊的对象。
它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。
这种官方的概念是比较难理解的,在面试的时候说出来也不是很专业,因为没办法有个具体的逻辑。
我个人认为,理解闭包的关键在于:外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。
什么是闭包呢?
其实上面的两种说法是一个意思:就是一个函数A可以访问另一个函数B的局部变量,即便另一个函数B执行完成了也没关系。我目前把满足这样条件的函数A叫做闭包。
闭包存在的价值和意思?
应用闭包的主要场合是:设计私有的方法和变量。
任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。私有变量包括函数的参数、局部变量和函数内定义的其他函数。
把有权访问私有变量的公有方法称为特权方法(privileged method)。
要把函数名和函数功能区分开,函数中的this是表达谁调用了这个函数,是很函数功能有关的。JS中函数的全局调用this是window。
在JS中闭包是一个很重要的概念,看下面俩篇文章
kotlin中也引入了Closure的概念,目前来看是差不多的
闭包的特点:
每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。
我理解,每次调用外部函数的时候,都相当于有了一个“新对象”,它们是互不干扰的
fun closureOuter(x : Int) : (Int) -> Int {
var a = 3
// return fun (y : Int) : Int {
// a++
// return a + x + y
// }
return {y ->
a++
a + x + y
}
}
var closureInner0 = closureOuter(3)
var closureInner1 = closureOuter(13)
println(closureInner0(3))
println(closureInner0(3))
println(closureInner1(3))
println(closureInner1(3))
kotlin的闭包和js还是有些不一样的,看下面的代码,kotlin这样写是对的,js这样写就不对,js需要再包一层函数调用
fun fn(): Array<(() -> Unit)?>{
var arr = arrayOfNulls<() -> Unit>(10)
for (i in 0..9) {
arr[i] = fun () {
println(i)
}
}
return arr
}
var arr1 = fn()
for (item in arr1) {
item?.invoke()
}