jinhailang / blog

技术博客:知其然,知其所以然
https://github.com/jinhailang/blog/issues
60 stars 6 forks source link

JavaScript关于闭包,匿名函数,this,对象等的一些理解 #12

Open jinhailang opened 7 years ago

jinhailang commented 7 years ago

闭包原本就是指所有的函数,但我们一般是指能够读取其他函数内部变量的函数,主要有两个作用:一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。匿名函数不但可以省去命名的问题,同时可以提高程序的安全性,增加内聚。this 指针的作用对象取决与其所在的运行环境,闭包是运行在 Window 全局的,所以闭包里面的 this 也是指向 Window 的。在 JavaScript 中一切都可以看见作对象,变量,函数等都可以用来创建对象。在 JS 中属性是公有的,但是有私有变量,使用 var 定义就是私有变量,同时也没有块级作用域的概念(注:for(var i=0;i<5;i++),i存在于整个函数),那怎么才能访问私有变量以及仿造块级作用域,跟其他语言一样的效果呢?

闭包+匿名函数就派上用场了。块级作用域可以使用自我执行来解决(注:function(){}()),为什么?这里要引入作用域链和内存回收的概念了。JS 中对象之间的关系是从下往上的,也就是说如果子函数还在引用,那么以上的所有父函数都不会被回收,所以上面的 for 循环就可以放在函数闭包里面自我执行,完了后,i就被回收了,相当于块级变量。

既然通过闭包等方式可以创建出跟其他语言一样的对象,那么也肯定可以达到一些特殊的模式设计效果了。比如,静态变量,单例模式。使用 prototype 使方法(如构造函数等)共享,从而使相应的变量变成静态变量。

JS 相对于 C++ 而言更加面向对象(貌似是个废话),两个语言的所有用法不同之处就在于此,JS 中的许多特性就是强制要使用者养成面向对象的概念,在语言层面很自然的能够设计出高内聚,低耦合的程序来。比较适合初学者,但 C++ 更加自由化一些,要有一定的功力才能达到这样的效果。