锁定老帖子 主题:(译)理解 JavaScript 闭包
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-25
最后修改:2011-12-27
前言: 理解JavaScript闭包——Javascript Closures是一篇经典文章。网上(包括iteye)有翻译的中文版本,但是有一个部分并未翻译。在学习的过程中,我决定翻译下来,让这篇经典文章有一个完整的中文版。基于自己是第一次翻译,肯定存在一些错误,一些部分采用了意译。翻译之后,对译文进行了三遍润色和修改,希望大家提出意见,继续改进这篇译文。 附件中是这篇文章的完整翻译版,已经整合进下面的内容,其他部分来自网络,在此感谢之前翻译的作者。 最后,希望能给大家带来写帮助。
正文 标识符解析
var example = "CaoLixiang"; var outer = function() { var example = "HuJin"; return function() { var example = "Love"; alert(this.example); } } var test = outer(); test(); // CaoLixiang
var age = 200; var sec = function() { var age = 100; return function() { var age = 22; alert(age); }; }; var test = sec(); test(); // 22 var age = 200; var sec = function() { var age = 100; return function() { alert(age); }; }; var test = sec(); test(); // 100 var age = 200; var sec = function() { return function() { alert(age); }; }; var test = sec(); test(); // 200 Object.prototype.age = 1000; var sec = function() { return function() { alert(age); }; }; var test = sec(); test(); // 1000
function exampleClosureForm(arg1, arg2){ var localVar = 8; function exampleReturned(innerArg){ return ((arg1 + arg2)/(innerArg + localVar)); } /* 返回对内部函数exampleReturned的引用 */ return exampleReturned; } var globalVar = exampleClosureForm(2, 4);
var secondGlobalVar = exampleClosureForm(12, 3);
一个新的执行环境将被创建,同时伴随一个新的活动对象,一个新的函数对象也会被返回,不同的[[scope]]属性将会是一个含有这个活动对象的作用链,这个活动对象包含:属性arg1,其属性值为12;arg2,其属性值为3。(为了方便后面的讨论,我们将这个活动对象记为”ActOuter2”) function callLater(paramA, paramB, paramC){ /* 返回一个匿名内部函数的引用,由一个函数表达式构成 */ return (function(){ /* 这个内部函数被setTimeOut调用执行;当它执行时可以读取、操作外部函数传递的参数。 */ paramA[paramB] = paramC; }); } /* 调用函数后将返回一个内部函数的引用。传递的参数将可以被内部函数读取和使用。*/ var functRef = callLater(elStyle, "display", "none"); /* 调用setTimeout函数, 传递内部函数的引用赋值给 functRef ,以functRef作为setTimeOut的第一个参数变量 */ hideMenu=setTimeout(functRef, 500);
function associateObjWithEvent(obj, methodName){ /* 返回的内部函数将被作为一个DOM元素的事件句柄 */ return (function(e){ /* 事件对象将被传递作为e参数 */ e = e||window.event; // 浏览器差异性 return obj[methodName](e, this); }); } function DhtmlObject(elementId){ var el = getElementWithId(elementId); if(el){ el.onclick = associateObjWithEvent(this, "doOnClick"); el.onmouseover = associateObjWithEvent(this, "doMouseOver"); el.onmouseout = associateObjWithEvent(this, "doMouseOut"); } } DhtmlObject.prototype.doOnClick = function(event, element){ // doOnClick method body. } DhtmlObject.prototype.doMouseOver = function(event, element){ // doMouseOver method body. } DhtmlObject.prototype.doMouseOut = function(event, element){ // doMouseOut method body. }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-12-26
楼上这个解释很深刻,以后多多向你学习。我把最近几个讨论闭包的例子都收集起来了,供大家参考。
http://www.iteye.com/topic/1119280 http://www.iteye.com/topic/1118705 http://www.iteye.com/topic/1118236 |
|
返回顶楼 | |
发表时间:2011-12-27
caolixiang 写道
var age = 200; var sec = function() { age = 100; return function() { alert(age); }; }; var test = sec(); test(); // 200 这个答案是错误的。test()返回的是100,而不是200啊!这个问题很严重啊! |
|
返回顶楼 | |
发表时间:2011-12-27
lib 写道 caolixiang 写道
var age = 200; var sec = function() { age = 100; return function() { alert(age); }; }; var test = sec(); test(); // 200 这个答案是错误的。test()返回的是100,而不是200啊!这个问题很严重啊! 楼主疏忽了,主要想反映 在原型链的一个个对象中寻找是否存在与标识符对应的属性,直到作用链被穷尽。 代码改为: var age = 200; var sec = function() { return function() { alert(age); }; }; var test = sec(); test(); // 200 再附上一个例子 |
|
返回顶楼 | |
发表时间:2011-12-27
panduozhi 写道 楼上这个解释很深刻,以后多多向你学习。我把最近几个讨论闭包的例子都收集起来了,供大家参考。
http://www.iteye.com/topic/1119280 http://www.iteye.com/topic/1118705 http://www.iteye.com/topic/1118236 +1 |
|
返回顶楼 | |
发表时间:2011-12-28
lib 写道
caolixiang 写道
var age = 200; var sec = function() { age = 100; return function() { alert(age); }; }; var test = sec(); test(); // 200 这个答案是错误的。test()返回的是100,而不是200啊!这个问题很严重啊!
楼主的文章我没看,但是冰哥你这个是有问题的。 你这样写虽然产生了闭包,但是age并不在一个理想的闭包空间内。随着 var test = sec(); 这步赋值操作,先是把全局变量的age重新赋值,然后再创建一个闭包。如果这段代码的最外层不是全局变量,影响的即为上级作用域,也就是说没有把age“闭”在闭包内。 说起来太抽象,你理解下这段代码
var age = 200; var sec = function() { age = 100; tt(); return function() { alert('3) '+age); }; }; var tt = function (){ alert('2) '+age) } alert('1) '+age) var test = sec(); test(); alert('4) '+age) |
|
返回顶楼 | |
发表时间:2011-12-29
日,404,你懂得
panduozhi 写道 楼上这个解释很深刻,以后多多向你学习。我把最近几个讨论闭包的例子都收集起来了,供大家参考。
http://www.iteye.com/topic/1119280 http://www.iteye.com/topic/1118705 http://www.iteye.com/topic/1118236 |
|
返回顶楼 | |
发表时间:2012-01-05
+1 不错
|
|
返回顶楼 | |
浏览 8503 次