今天有同学问了关于什么是闭包,其实闭包很难说清楚,下面我就把我的理解给大家分享一下,有不对的地方大家指出。
你这里的闭包其实就是指的函数闭包。
关于闭包讲起来很麻烦,闭包只是一个概念 JAVA C# JavsScript都有闭包,其实就是变量作用的问题。我理解的闭包就是变量生命周期结束后还可以调用。这里的“闭” 不是封闭的而是“闭合”,物理上解释是首位相连形成环路。 这里意思是重新与此变量的作用域相连,让其它成员可以重新调用。
举个例子
class Person
{
public string Name = "张三";
public void SayHello()
{
Consolw .WriteLine(name);
}
}
Person p= new Person();
p.SayHello();
大家想想问什么会输出张三这个结果。其实要研究又得研究内存分配 那些底层关系等,很麻烦,也没有必要。其实这就是一条规则,内部实现交给.net了,类成员间当然可以互相调了(不大严谨 那些static 就不管了). 这是.net中class的规定。
大家想想 如果换种方式。
public delegate void mydelegate();
class Person
{
static public mydelegate SayHello()
{
string name = "张三";
return () =>
{
Console.WriteLine(name);
};
}
static void Main()
{
mydelegate p = SayHello();
p();
Console.ReadKey();
}
}
大家思考一下SayHello();调用已经调用结束了,此时name变量在栈区已经销毁了 为什么say()还可调用name;这其实就是闭包。name的作用域已经重新闭合了。其实这只是表面现象 name的作用域不是已经开启 而是通过委托帮了忙。此时的name的变量确实已经销毁了 。但是大家知道委托其实是一个特殊的类 继承自Dellegate。其实编译器自动将name复制给了委托这个类中由的属性。这个属性是由编译器自动生成的假设是newname。大家知道类中的属性是可以相互访问的,所以newname可以被匿名函数访问。他俩都是类中的成员,而且访问级别相同。这些过程是由编译器完成的,无需我们关心。这就是为什么说委托是个一个特殊的类。
再举一个JavaScript中的闭包的应用。
JavaScript也就是函数闭包的应用 就是JS的面向对象编程。也就是通过函数闭包来构造所谓的类。
例如:
function Person() {
this.Name = "张三";
this.SayHello = function () {
alert(this.Name);
};
}
var p = new Person();
p.SayHello();
其实杨中科老师视频说过类不是类其实累是对象。这就是采用函数闭包将JS将函数对象封装成了类。(这就是为什么JS是基于对象的了,类其实也是对象.)
js闭包和和C#道理差不多. 其实也可以这样写
function Person() {
var Name = "张三";
return function () {
alert(Name);
};
}
var p = Person();
p();
这样就和 上面那个C#差不多了吧 。
也可以这样理解:闭包 就是:一个女士她很爱美,所以买了一个漂亮的梳子。因为梳子很漂亮她既想放在家里欣赏又想放在包里随身用。怎么办呢?所以她又买了一个一样的梳子放到包里,然后用的时候拿出来就行。这就是闭包。与前面所说的闭合 有点差别。写的有不对的,大家原谅。
写这篇文章写了俩小时。希望帮到你。
c
}
|