您的位置:首页 > Web前端 > JQuery

[从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)(转)

2010-05-07 00:39 1086 查看
http://blog.csdn.net/natineprince/archive/2009/11/02/4759533.aspx

jQuery片段:

view plaincopy to clipboardprint?

(function(){

//这里忽略jQuery所有实现

})();

view  plaincopy  to clipboardprint?

function abc(){

// code to process

}

function  abc(){   // code to process }

  当然,你的函数也可以是带参数的,甚至是带返回值的。

view plaincopy to clipboardprint?

function abc(x,y){

return x+y;

}

view  plaincopy  to clipboardprint?

alert(typeof abc);// "function"

alert(typeof abc);// "function"

  你的浏览器就会弹出提示框,提示你abc是一个Function对象。那么Function对象究竟是什么呢?

Function 对象

  Function对象是JavaScript里面的固有对象,所有的函数实际上都是一个Function对象。关于这个方面的讨论,我们留到下 一个专题节。我们先看看,Function对象能不能直接运用构造函数创建一个新的函数呢?答案是肯定的。例如:

view plaincopy to clipboardprint?

var abc = new Function("x","y","return x*y;");

alert(abc(2,3)); // "6"

view  plaincopy  to clipboardprint?

alert(typeof function(){});// "function"

alert(typeof function(x,y){return x+y;});// "function"

alert(typeof new Function("x","y","return x*y;"))// "function"

alert(typeof  function(){});// "function" alert(typeof function(x,y){return x+y;});// "function" alert(typeof new Function("x","y","return x*y;"))// "function"

  我们可以很容易地看到,它们全都是Function对象,换言之,他们都是函数,但是他们都有一个特点——没有名字。所以我们把他们称作“匿名 函数”。然而,正因为他们没有“名字”,我们也没有办法找到他们。这就引申了如何去调用一个匿名函数的问题了。

匿名函数的调用

  要调用一个函数,我们必须要有方法定位它,引用它。所以,我们会需要帮它找一个名字。例如:

view plaincopy to clipboardprint?

var abc=function(x,y){

return x+y;

}

alert(abc(2,3)); // "5"

view  plaincopy  to clipboardprint?

alert((function(x,y){return x+y;})(2,3));// "5"

alert((new Function("x","y","return x*y;"))(2,3));// "6"

alert((function(x,y){return  x+y;})(2,3));// "5" alert((new Function("x","y","return x*y;"))(2,3));// "6"

  很多人或许会奇怪,为什么这种方法能成功调用呢?觉得这个应用奇怪的人就看一下我以下这段解释吧。

  大家知道小括号的作用吗?小括号能把我们的表达式组合分块,并且 每一块,也就是每一对小括号,都有一个返回值。这个返回值实际上也就是小括号中表达式的返回值。所以,当我们用一对小括号把匿名函数括起来的时候,实际上小括号对返回的,就是一个匿名函数的Function对象。 因此,小括号对加上匿名函数就如同有名字的函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会实现普通函数的调用形式。

  不知道以上的文字表述大家能不能看明白,如果还是理解不了的话,再看一下以下的代码试试吧。

view plaincopy to clipboardprint?

var abc=function(x,y){return x+y;};// 把匿名函数对象赋给abc

// abc的constructor就和匿名函数的 constructor一样了。也就是说,两个函数的实现是一样的。

alert((abc).constructor==(function(x,y){return x+y;}).constructor);

view  plaincopy  to clipboardprint?

var abc=function(y){

var x=y;// 这个是局部变量

return function(){

alert(x++);// 就是这里调用了闭包特性中的一级函数局部 变量的x,并对它进行操作

alert(y--);// 引用的参数变量也是自由变量

}}(5);// 初始化

abc();// "5" "5"

abc();// "6" "4"

abc();// "7" "3"

alert(x);// 报错!“x”未定义!

var abc=function(y){ var x=y;// 这个是局部变量 return function(){   alert(x++);// 就是这里调用了闭包特性中的一级函数局部变量的x,并对它进行操作   alert(y--);// 引用的参数变量也是自由变量 }}(5);// 初始化 abc();// "5" "5" abc();// "6" "4" abc();// "7" "3" alert(x);// 报错!“x”未定义!

  看到这里,你能判断究竟jQuery的那个代码片段是否闭包了吗?

  以我的理解来说吧。是否应用了闭包特性,必须确定该段代码有没有 最重要的要素:未销毁的局部变量。那么很显然,没有任何实现的匿名函数不可能应用了闭包特性。但如果匿名函数里面有实现呢?那也还得确定它的实现中有没有 用到那些未销毁的局部变量。所以如果问你那个开篇中的jQuery代码片段是应用了JS里的什么特性?那么它只是匿名函数与匿名函数的调用而已。但是,它 隐含了闭包的特性,并且随时可以实现闭包应用。因为JS天生就是有这个特性的!(这只是我的理解,我也想知道你的理解,欢迎交流!关于闭 包,有机会还是独立再开一个专题吧!)

  在这里向以前理解错误时,在回答CSDN各位问题的时候所作的错误回答道歉——Sorry...

  由于本笔记是走读jQuery时引申出的JS知识点整理,所以可能和真正的JS学习不搭旮,建议初学JS的人还是先看看基础的书籍吧。不过接下 来的几章应该都是对JS基础的整理了,对此篇阅读有困难的同学可以先查看后面的章节。谢谢支持!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐