函数表达式---闭包
来源:互联网 发布:java 整型 编辑:程序博客网 时间:2024/06/05 21:02
闭包:
有权访问另一个函数作用域内变量的函数。常见的方式就是在一个函数的内部创建另外一个函数。
function a(){ var color = "red"; function b(){ alert(color); } b(); } a(); a内的b可以访问a的内部变量color;
注意:由于闭包会携带包含他的函数的作用域(例如闭包携带包含b的a这个函数的作用域),所以比其他的函数占更多的内存。过度使用闭包会导致内存占用的过多。谨慎使用闭包。
1.闭包和变量
副作用:闭包只能取到包含函数中任何变量的的最后一个值。
function a(){ var arr = []; for(var i = 0;i < 10;i++){ arr[i] = function(){ return i; }; } return arr; } console.log(a()[0]())//10 console.log(a()[3]())//10 console.log(a()[8]())//10
上面的这个闭包内的函数,看起来是0位置的函数返回0,以此类推,其实不是。每一个函数的作用域中都保存着a()函数的活动对象,他们引用的是同一个变量i,当a()运行结束,i返回为10,此时每一个函数引用的变量i是同一个变量对象,所以每一个函数的内部i都是10.
可以利用下面的方式实现: function a(){ var arr = []; for(var i = 0;i < 10;i++){ arr[i] = function(num){ return function(){ return num }; }(i); } return arr; } console.log(a()[0]())//0 console.log(a()[3]())//3 console.log(a()[8]())//8
我们没有直接将闭包赋值给数组,而是定义了一个匿名函数,并将立即执行该函数的结果赋值给数组。(立即执行函数(function(num))(i)中的第二个()为调用函数,i为传入的参数)。这样就将不同的i赋值给了num,而在匿名函数的内部有返回一个访问num的闭包,这样一来数组arr中的每一个元素所对应的的函数都有自己的num变量。
2.关于this
this是函数运行的环境所决定的,在全局调用函数,this就是window。函数被当做某个对象的方法调用时,this就是这个对象。 不过,匿名函数的执行环境具有全局性,因此this对象通常指向window。
var name = "this is window"; var obj = { name:"opbject", say:function(){ return function(){ alert(this.name); }; } }; obj.say()();//"this is window"
这是因为obj.say()其实是返回了匿名函数: function(){ alert(this.name); }; 然后又在全局环境下调用了,所以this指向window。
也可以让闭包访问obj对象 var name = "this is window"; var obj = { name:"opbject", color:"red", say:function(){ var that = this; return function(){ alert(that.name); }; } }; obj.say()();//"opbject" 因为that指向的就是obj。
在某些特殊的环境下this会发生改变。 var name = "this is window"; var obj = { name:"opbject", say:function(){ alert(this.name); } }; obj.say();//"opbject" (obj.say)();//"opbject"
因为this.name就是obj.name (obj.say = obj.say)()//"this is window" 这是因为复制了函数,函数与obj没有关系了,只是函数,在全局环境下调用,所以this=window
3.内存泄露
如果闭包的作用域链保存一个HTML元素,就会造成内存泄漏。
function a(){ var b = document.getElementById("hcd"); //b用完之后一直驻留在内存 b.click = function(){ alert(b.id) } }
如果想回收内存,那么引用数需要可以减少为0,但是b在闭包内至少被引用了1回,导致内存无法回收。
function a(){ var b = document.getElementById("hcd"); var id = b.id; b.click = function(){ alert(id) } b = null; }
这样就可以了,因为闭包会引用包含函数在内的活动对象,而变量b是活动对象的一个属性,所以任然会有一个引用。 所以用必要将b=null
阅读全文
0 0
- 函数表达式---闭包
- 函数表达式与闭包
- 函数表达式和闭包
- JavaScript 函数表达式 闭包
- JavaScript函数表达式和闭包
- 函数表达式-闭包,作用域链
- javascript中函数表达式,闭包
- 【JavaScript学习】函数表达式:闭包
- js函数--函数声明;函数表达式;闭包
- JavaScript学习笔记之函数表达式与闭包
- python3 入门 (三) 函数与lambda表达式、闭包
- JavaScript基础——函数表达式、闭包
- C++11闭包函数:Lambda表达式的使用λ
- js高级程序设计笔记4--函数表达式及闭包
- 闭包与立即调用函数表达式IIFE 20170208
- 第七章:函数表达式(简述、递归和闭包)
- java1.8 lambda表达式 函数式编程 闭包
- 第七章 函数表达式(闭包重点)
- lung cancer detection
- 函数参数的传递方式及一些容易出现的问题
- pandas入门——文件读取与写入
- 优酷播放按钮动画原理解析
- java代码实现CSV文件读取、将数据拆分成多个CSV文件及数据导出到CSV文件
- 函数表达式---闭包
- 命令行编辑 快捷键
- 达内课程-布局控件之相对布局和线性布局
- 《视频直播技术详解》系列:(7)推流和传输
- HDU 6096 String(2017 Multi-University Training Contest 6)
- 全排列及相关扩展算法(二)——求字典序下一组排列及全排列算法
- StringUtils中isEmpty 和isBlank的区别
- 如何部署 OS X 上 Sublime Text 3 + LaTeX 的中文环境?
- JavaScript块级作用域与函数作用域