初始JavaScript-闭包
来源:互联网 发布:企政oa软件下载 编辑:程序博客网 时间:2024/04/30 07:37
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
function createComparisonFunction(property) { return funtcion (f1,f2) { return f1(property) == f2(property); }}
f1()
和f2()
都能访问到createComparisonFunction)
函数的property
属性,是因为f1()
和f2()
函数的作用域中包含createComparisonFunction()
的作用域。
当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后,使用 arguments 和其他命名参数的值来初始化函数的活动对象(activation object)。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,……直至作为作用域链终点的全局执行环境。
下图为下面代码实现时的函数的作用链:
var compare = createComparisonFunction("name");var result = compare({ name: "Nicholas" }, { name: "Greg" });
从上图可以看出:
- 全局变量对象是一直存在的,而局部变量只在函数执行过程中存在。
- 函数的作用链中,函数本身的
arguments
在第一位,外部createComparisonFunction
函数的arguments
排在第二位,而全局变量对象处在第三位。
//获得其匿名函数var compare = createComparisonFunction("name");var result = compare({ name: "Nicholas" }, { name: "Greg" });
在匿名函数从 createComparisonFunction()
中被返回后,它的作用域链被初始化为包含createComparisonFunction()
函数的活动对象和全局变量对象。
当 createComparisonFunction()
函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中;直到匿名函数被销毁后, createComparisonFunction()
的活动对象才会被销毁,
所以在清除闭包函数时,不仅需要将函数清除,也需要清除函数内的闭包。
闭包与变量
作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
如下面例子:
function createFunctions(){ var result = new Array(); for (var i=0; i < 4; i++){ result[i] = function(){ return i; };}return result;//返回的结果result[0]=result[1]=result[2]=result[3]=4;}
上面例子的作用链图如下:
可以看出i是createFunctions
函数的活动对象,所以内部函数引用的都是同一个i,当createFunctions
返回后,i为4,所以数组中值都为4。
解决上面问题方法就是创建另一个匿名函数。
function createFunctions(){ var result = new Array(); for (var i=0; i < 4; i++){ result[i] = function(num){ return function(){ return num; }; }(i); } return result;}
定义了一个匿名函数,并将立即执行该匿名函数的结果赋给数组。这样函数当时执行的i值,会立即传给num。在这个匿名函数内部,又创建并返回了一个访问 num 的闭包。这样一来, result 数组中的每个函数都有自己num 变量的一个副本,因此就可以返回各自不同的数值了。
关于this对象
this 对象是在运行时基于函数的执行环境绑定的:在全局函数中, this 等于 window,而当函数被作为某个对象的方法调用时, this 等于那个对象。不过,匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window。
function func1() { alert(this);}func1();//window
直接定义函数func1
,相当于在全局环境下定义,所以this指向window。
var o = { name: "object", func2:function() { alert(this); }};o.func2();//object
此时,函数是通过对象o调用,所以this指向object。
var name = "The Window";var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; }};alert(object.getNameFunc()()); //"The Window"(在非严格模式下)
object.getNameFunc()
返回的是匿名函数,此时不是通过getNameFunc()
函数调用的,所以this指向window。
var name = "The Window";var object = { name : "object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; }};alert(object.getNameFunc()()); //"My Object"
在getNameFunc()
中this指向的My Object
,所有先赋值给that,然后匿名函数返回时,that的值仍然保持,所以最后返回的是My Object
。
- 初始javascript闭包
- 初始JavaScript-闭包
- 初始JavaScript
- 初始JavaScript
- 初始JavaScript
- 【JavaScript】Javascript闭包
- 初始JavaScript中的模块
- 初始javaScript笔记
- javascript的闭包javascript
- Javascript闭包演示javascript
- [ javascript ] javascript闭包测试!
- 【javascript】javascript中的闭包
- 【javascript】学习Javascript闭包
- 理解 JavaScript 闭包
- javascript 闭包
- javascript闭包
- Javascript闭包
- JavaScript中的"闭包"
- Cocos2D-X学习13:交互功能——鼠标和键盘
- linux学习笔记--用户和组
- 耦合与内聚
- internal关键字
- 数组逆序
- 初始JavaScript-闭包
- Activity的生命周期,BACK键和HOME键生命周期
- 火狐浏览器的同步问题
- JavaScript
- 数据库查询相隔同等时间段的数据量
- 第十四周 OJ 进制转换
- Vistual studio 2013 F5调试.NET项目时未编译当前项目及其依赖项目
- 插入有序数组中
- 那些年苹果这样改变了电脑处理字体的方式