闭包(1)初识闭包
2015-12-03 22:16
302 查看
一、初识闭包
起初,我对闭包的理解简单粗暴:函数里嵌套的函数就是**闭包**!且内部函数可以访问外部函数的变量,外部函数却无法探知内部的函数变量。 类似Java里被private修饰的类。且闭包也可以设置私有成员,但是关系到内存、垃圾回收却是没什么好比较的。 **闭包**的正经定义是:把有权访问另一函数作用域的变量的函数称为**闭包**。 ECMAScript中提到**闭包**: 1.即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从外部函数中返回)。换句话说:内部函数在外部函数返回后被执行了。 2.在代码中引用了自由变量。 ------这里都有关系到**作用域链**和**垃圾回收机制**(*下文会提到*),这种机制也使得闭包能够保存数据。
二、关于作用域
JavaScript不像其他C、Java那种块级作用域,JavaScript只有函数作用域。像if(){}或者for(){},这样带花括号的语句是没有用的。
如下:
<script> if(1){ var noway = "这个花括号关不住我哈哈哈";} console.log(noway); </script>
了解作用域之后我们应该要认识作用域链了,这关系到函数之间的访问机制。
functon a(){ var n = 1; function b(){ var m =2; } }
在这里内部函数的作用域可以通过**作用域链**来访问所有的外部作用域中的变量和函数,作用域链把这些作用域串起来, 这样每个作用域都可以向上搜索、访问。不可向下。这也是**闭包**存在的关键所在。 作用域链本质是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
三、闭包的作用
**1、读取函数内部的变量**(可以设置私有变量,可像Java一样写 set()、get()方法)
例:
function Tree(name){ this.get = function(){ return name; }; this.set = function(value){ name = value; }; } var tree = new Tree("apple");//apple console.log(tree.get()); tree.set("pear"); console.log(tree.get());//pear
this.set = function(name){ this.name = name; }//并不可以像Java一样写
2、让某些变量的值保存在内存中不被回收,实现数据共享。
在JavaScript中,在函数声明里的函数都是局部的,函数运行完后就会被释放掉。 但是如果这个作用域依旧在被引用(与全局变量有关联,或是说作用域链依旧存在),那函数就会被留在内存。 细节可以看看JavaScript的**垃圾回收机制**。
var a = function (){ var n = 0; return function () { console.log(n++); } var o = a();//赋值给了全局变量,var 也可去掉 console.log(a()); o();//0 o();//1 o();//2 a()();//0 a()();//0 a()();//0
ps:(1)关于为什么var可以去掉,是因为使用var声明的变量会被添加到最近的作用域中,如上o加入到了全局环境。(2)如果初始化变量时没有使用var来声明, 那么该变量会被自动加到全局环境中。
推荐书籍:《JavaScript高级语言程序设计》 《JavaScript权威指南》
推荐博客 :http://web.jobbole.com/84328/
《大部分人都会做错的经典JS闭包面试题》
可以作为学习成果的检验
望多指正,文章也会不断修改扩充。
相关文章推荐
- 用文章和视频的app例子简介React-Native
- 通俗理解马尔科夫链
- 在MAC下面用 eclipse调试android 6.0 framework
- [置顶] struts2笔试面试
- setTimeout()&&setInterval()实例
- hibernate一对一对应关系
- jquery 生成表格,拆分,合并
- 有穷自动机
- 实验三 进程模拟调度
- Android 关于“NetworkOnMainThreadException”解决办法
- 【学习ios之路:UI系列】ios中常见的几种控件.(UISlider,UISwitch,UIStepper,UISegmentedControl)
- 优化mysql limit offset
- iOS UITextField实用实现手机账号344格式 —— HERO博客
- java总结
- hdoj2045(涂色+递归)
- 需求分析
- lijhtoj Integer Divisibility (简单同余数题)
- CentOS 6.x的安装过程及实现自动安装
- 我的开源项目:一种TLV编解码器的实现
- 我的开源项目:一种TLV编解码器的实现