javascript中的闭包
2016-01-06 09:59
615 查看
js中的闭包已经有很多论断了,大家伙有没有听懂了,先引用一片比较高端 的 ”汤姆大叔“ 深入理解JavaScript系列(16):闭包(Closures)
好了,为了引起大家的兴趣,先来小诗一首
论点:所有函数都是闭包,闭包在创建的时候就保存了上下文的作用域链,同一个上下文创建的闭包共用一个作用域链
尼玛,上面的论点看了咋那么虚了,不急,容鄙人娓娓道来
先来解释下到底啥是如此高端的”作用域链“,
”每一段js代码(全局代码和函数)都有一个与之关联的作用域链,这个作用域链是一个对象列表或者链表,这组对象定义了这段代码
‘作用域中的变量’,当js需要查找变量x的值得时候(变量解析),它会从链的第一个对象开始查找,如果这个对象有个一个名为x的属性,则直接使用这个属性的值,如果不存在x属性,js会查找链上的下一个对象,如果仍然没有则继续下一个对象,以此类推。如果该链上没有任何一个对象用于x属性,那么就认为该段代码作用域链上不存在x,最终抛出一个引用异常错误“
以上说法应该了解了吧,如果不了解,不要紧,请持续关注鄙人的博客,到时鄙人会专门写篇文章论述这个玩意
先来看一个经典的关于闭包的现象
这个结果是弹出”6“,当然你即便使用"funcs[1]()"还是弹出"6", 我们尝试使用上面的理论来解释这一现象。
这里会产生5个函数,即 funcs[1]...funcs[5], 这些函数在定义时都会定义一个作用域链,由于他们的作用域链是相同的(记得上面的理论吗"同一个上下文创建的闭包共用一个作用域链"),这个链上有'i'这个属性,当然了这个作用域链的属性是一个引用而非拷贝,因此每次循环将会改变'i'的值,直至循环5次后,又将'i'加了1,最终变为了6, 由于作用域链中的属性'i'引用了变量'i',所以作用域链对象中的属性'i'最终都变为6,那么每个函数在执行时都会去查找作用域链中的'i'属性,都是6.
再来看一个例子,十分有趣啊,似乎记住了自己的过去
你是不是以为会弹出"20", 如此的话恭喜你中标了,结果是"10"。看起来好像记住了过去似得,十分诡异。
我们尝试使用上的逻辑来解释这一现象,首先函数'lizi'在全局代码中创建的,想想上面的理论("闭包在创建的时候就保存了上下文的作用域链"),'lizi'在创建时就保存了自己的作用域链,该链上有属性'z',值为'10'。后面在匿名函数中又声明了变量'z' 且赋值20, 但是匿名函数和前面的全局代码上下文是不一样的, 所以他们的作用域链也是不同的,匿名函数中不仅有global的作用域链,还有匿名函数本身的作用域链(该链在global链上增加了一些东西),不过这两个链中都有属性'z'。在匿名函数中调用'lizi'
,'lizi'会到自己在定义时保存的作用域链上查找'z' 发现'z'的值为10. 该处如果全局代码中没有定义'z', 你即便在匿名函数中定义了'z', 'lizi'中仍然会弹出未定义,不信,有如下代码为证
上面一段代码,要是不报错,请骂我!!!
再来一段代码,自己按照上面的理论去解释,然后猜,到底是啥
自此,闭包产生的原因和导致的结果算是讲完了
尼玛,说了这么多,这个闭包放在这里难道故意装逼为难我们,到底在实践中有啥用了?
先弄个面向对象中高大上的用法,"私有变量" , 私有变量自然只能是内部可以更改访问,外部就不行了
怎么样,是不是有写'java','php'之流的感觉
转载地址:http://www.cnblogs.com/painsOnline/p/5102361.html
好了,为了引起大家的兴趣,先来小诗一首
var funny1 = function(word){ var base = '天上的云啊,'; alert(base + word); return funny1; } funny1('真白!')('很白!')('贼白!')('太他妈白!');
论点:所有函数都是闭包,闭包在创建的时候就保存了上下文的作用域链,同一个上下文创建的闭包共用一个作用域链
尼玛,上面的论点看了咋那么虚了,不急,容鄙人娓娓道来
先来解释下到底啥是如此高端的”作用域链“,
”每一段js代码(全局代码和函数)都有一个与之关联的作用域链,这个作用域链是一个对象列表或者链表,这组对象定义了这段代码
‘作用域中的变量’,当js需要查找变量x的值得时候(变量解析),它会从链的第一个对象开始查找,如果这个对象有个一个名为x的属性,则直接使用这个属性的值,如果不存在x属性,js会查找链上的下一个对象,如果仍然没有则继续下一个对象,以此类推。如果该链上没有任何一个对象用于x属性,那么就认为该段代码作用域链上不存在x,最终抛出一个引用异常错误“
以上说法应该了解了吧,如果不了解,不要紧,请持续关注鄙人的博客,到时鄙人会专门写篇文章论述这个玩意
先来看一个经典的关于闭包的现象
var funcs = []; for(var i =1; i <= 5; i++){ funcs[i] = function(){alert(i);} } funcs[5]();
这个结果是弹出”6“,当然你即便使用"funcs[1]()"还是弹出"6", 我们尝试使用上面的理论来解释这一现象。
这里会产生5个函数,即 funcs[1]...funcs[5], 这些函数在定义时都会定义一个作用域链,由于他们的作用域链是相同的(记得上面的理论吗"同一个上下文创建的闭包共用一个作用域链"),这个链上有'i'这个属性,当然了这个作用域链的属性是一个引用而非拷贝,因此每次循环将会改变'i'的值,直至循环5次后,又将'i'加了1,最终变为了6, 由于作用域链中的属性'i'引用了变量'i',所以作用域链对象中的属性'i'最终都变为6,那么每个函数在执行时都会去查找作用域链中的'i'属性,都是6.
再来看一个例子,十分有趣啊,似乎记住了自己的过去
var z = 10; var lizi = function(){ alert(z); } ;(function(){ var z = 20; lizi(); })();
你是不是以为会弹出"20", 如此的话恭喜你中标了,结果是"10"。看起来好像记住了过去似得,十分诡异。
我们尝试使用上的逻辑来解释这一现象,首先函数'lizi'在全局代码中创建的,想想上面的理论("闭包在创建的时候就保存了上下文的作用域链"),'lizi'在创建时就保存了自己的作用域链,该链上有属性'z',值为'10'。后面在匿名函数中又声明了变量'z' 且赋值20, 但是匿名函数和前面的全局代码上下文是不一样的, 所以他们的作用域链也是不同的,匿名函数中不仅有global的作用域链,还有匿名函数本身的作用域链(该链在global链上增加了一些东西),不过这两个链中都有属性'z'。在匿名函数中调用'lizi'
,'lizi'会到自己在定义时保存的作用域链上查找'z' 发现'z'的值为10. 该处如果全局代码中没有定义'z', 你即便在匿名函数中定义了'z', 'lizi'中仍然会弹出未定义,不信,有如下代码为证
var lizi = function(){ alert(z); } ;(function(){ var z = 20; lizi(); })();
上面一段代码,要是不报错,请骂我!!!
再来一段代码,自己按照上面的理论去解释,然后猜,到底是啥
var one; var two; var three = function(){ var x = 1; one = function(){ return ++x; } two = function(){ return --x; } alert(one()); } three(); alert(one()); alert(two());
自此,闭包产生的原因和导致的结果算是讲完了
尼玛,说了这么多,这个闭包放在这里难道故意装逼为难我们,到底在实践中有啥用了?
先弄个面向对象中高大上的用法,"私有变量" , 私有变量自然只能是内部可以更改访问,外部就不行了
var conuter = function(){ var count = 0; return { 'count':function(){return count++;}, 'reset':function(){count = 0}, 'get':function(){return count;} }; } var c = conuter(); alert(c.get()); c.count(); alert(c.get());
怎么样,是不是有写'java','php'之流的感觉
转载地址:http://www.cnblogs.com/painsOnline/p/5102361.html
相关文章推荐
- json序列化和反序列化
- js实现仿qq消息的弹出窗效果
- JavaScript学习总结(10)——实用JS代码大全
- JavaScript学习总结(10)——实用JS代码大全
- JavaScript学习总结(10)——实用JS代码大全
- JSP中调用Java代码的设计
- extjs-html配置
- this,this,再次讨论javascript中的this,超全面
- three.js学习笔记 基础1_1
- [jstips]undefined和null的区别
- JavaScript类型系统之基本数据类型与包装类型
- 实验十一:jstack使用
- json对象转化字符串、数组
- 4种JavaScript实现简单tab选项卡切换的方法
- js只保留整数,向上取整,四舍五入,向下取整等函数
- js获取多个标签元素的内容,并根据元素的内容修改标签的属性
- js针对ip地址、子网掩码、网关的逻辑性判断
- js判断当前页面在移动设备还是在PC端中打开
- js判断当前页面用什么浏览器打开的方法
- javascript中闭包(Closure)详解