javascript中的闭包以及dojo中的dojo.hitch()
来源:互联网 发布:数值最优化 高立 pdf 编辑:程序博客网 时间:2024/05/01 19:42
一、javascript的高级特性--闭包
理解closure前,首先明白函数作用域的概念。也就是全局变量和局部变量。在函数体内部可以调用全局变量,而函数体内被申明的变量不能被外部调用。
其次,要理解javascript中的垃圾回收机制,在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
了解这两个概念后,我们在看闭包。
“官方”给出的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
function a() { var i = 0; function b() { alert(++i); } return b;}var c = a();c();
在这里,a被b引用了。而b又被c引用了。这是对象不会被gc回收。这就形成了所谓的闭包。也就是说,在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
好了,深入理解之。再引入一片概念(copy....)
函数的执行环境(execution context)、活动对象(callobject)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。
- 当定义函数a的时候,js解释器会将函数a的作用域链(scopechain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scopechain中只有window对象。
- 当执行函数a的时候,a会进入相应的执行环境(excutioncontext)。
- 在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scopechain。即a.scope=a的作用域链。
- 然后执行环境会创建一个活动对象(callobject)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
- 下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
- 最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。
到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。
在理解原理之后,我们来看看引用场景。
1.保护了函数a的安全性。
2.在内存中维持一个变量。
3.通过保护变量的安全实现JS私有属性和私有方法。
二、dojo.hitch()
看完闭包后,再来说说,我写本文的目的。dojo.hitch(scope,method).
官方解释是:Dojo.hitch is a neat function. It returns a function thatwill execute a given function in a given scope. This functionallows you to control how a function executes, particularly inasynchronous operations。
看以下代码:
var args = { url: "foo", load: this.dataLoaded};dojo.xhrGet(args);
这段代码执行会怎么样呢?会报错。说dataLoaded不是个方法,或找不到。为什么呢。从代码中可以看出参数args的load想调用外部一个dataLoaded的方法。但是this引用却指向了args。而args里面可没有dataLoaded。
如何解决呢?
var args = { url: "foo", load: dojo.hitch(this, "dataLoaded")};dojo.xhrGet(args);
说到了hitch,我们就来看看它在dojo库里是怎么实现的?
在说原理之前,还是一样先引入两个javascript的方法,
这两个函数所做的事情没有太多差别,差异在于他们传入的参数,一个是args任意参数,一个是数组的参数。
大致用法如下,obj1.method.call(obj2,argument1...),
call的作用就是把obj1的方法放到obj2上使用,后面的argument1..这些做为其他参数传入。也可以说是obj1能够劫持obj2的方法并继承obj2的属性。
继承?对,就是继承。我们可以这么做。
结果是 dog sleep!!。
Animal.call(this)就使得,用Animal对象代替Dog中的this对象,这样Dog也就继承了Animal中的所有属性和方法了。这就实现了javascript里的继承。
结果是Animal eat!!!! 和dog eat!!!这就是常规的用法了。让方法执行在dog的作用域上。this.name就变成了dog。
嗯,很熟悉吧。其实dojo.hitch()也是这么做的。它用的是apply方法。在前面也提到了,apply和call只有参数的区别。
dojo.hitch = function(scope, method ){ if(arguments.length > 2){ return d._hitchArgs.apply(d, arguments); // Function } if(!method){ method = scope; scope = null; } if(d.isString(method)){ scope = scope || d.global; if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); } return function(){ return scope[method].apply(scope, arguments || []); }; // Function } return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function };
注:本文转载于http://www.cnblogs.com/Asure/archive/2012/08/15/2640093.html,感谢原文作者!
- javascript中的闭包以及dojo中的dojo.hitch()
- Javascript的回调,闭包与dojo.hitch
- Dojo 扩展 javascript 核心库 - dojo.hitch
- Dojo 扩展 javascript 核心库 - dojo.hitch
- Dojo 扩展 javascript 核心库 - dojo.hitch
- 用dojo.hitch避免闭包使用的一种方法
- dojo中的dojo/on
- dojo中的dojo/text!
- dojo dojo中的事件处理
- dojo中的dojo/dom-construct
- dojo中的dojo/dom-class
- dojo中的dojo/dom-style
- dojo中的dojo/dom-attr
- Dojo 学习笔记 之 Dojo hitch&partial
- dojo.hitch与dojo.partial解析
- dojo中lang.hitch()用法
- JavaScript中的AMD规范以及dojo中的AMD(程序员之家)
- Dojo 中的拖拽
- 百度地图中添加动态热力图
- Asp.Net前台调用后台变量的方法
- SQL语句快速参考
- jquery中attr()和prop()的区别
- Dojo与jQuery的比较
- javascript中的闭包以及dojo中的dojo.hitch()
- SQL2008升级SQL2008R2完全教程
- 世界坐标系和相机坐标系,图像坐标系的关系
- ArcGIS10.1桌面怎么使用ArcSDE服务
- 《用地图说话》资源下载完全汇总
- int *p = new int[10]; int *p = new int(10); http://bbs.csdn.net/topics/340186719
- SQL:将查询结果插入到另一个表的三种情况
- Javascript模块化编程--require.js(上)
- 1921: 绝对值排序