转至:
http://hi.baidu.com/zwnjiejie/blog/item/3f3c8a89506358be0e244456.html/cmtid/fcdc252a532d2c95023bf67e#0
javascript 匿名函数的理解,js括号中括function 如(function(){})
2010-06-28 15:31
代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })();
半年前初次接触jQuery的时候,我也像其他人一样很兴奋地想看看源码是什么样的。然而,在看到源码的第一眼,我就迷糊了。为什么只有一个匿 名函数又没看到运行(当然是运行了……),就能有jQuery这么个函数库了?于是,我抱着疑问来到CSDN。结果相信现在很多人都很清楚了(因为在我之 后也不乏来者,呵呵~)。当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来!真神奇哦! 嘿嘿!胡闹到此为止。在这一节,我们碰到的jQuery片段是一组立即运行的匿名函数。而这种用法在论坛上也曾引起过激辩——这段代码究竟属不 属于闭包呢?带着这个疑问,我们从基础开始,分析每个关键要素,寻找属于自己的答案。(没错,自己的答案!在我看来,所有理论只是形式,只要它有利于我们 的应用实现,就是可取的——黑猫白猫,抓到老鼠的就是好猫!) 要说匿名函数,我们首先要由函数本身说起。函数的定义如下: 函数是将唯一的输出值赋予给每一输入的“法则”。 当然,这只是数学上的定义。但是,在计算机编程语言中,函数的定义也八九不离十。因为,我们都知道,计算机中的函数,也类似数学定义中的描述,它是将输入的若干数据,经过代码设定的逻辑操作处理后,返回唯一的输出的一组代码组合块。——当然,特例是,输入的数据为空或输出的数据为空,或者两者都为空。 下面,我们先初步了解一下和匿名函数相关的概念。 函数声明(function 语句) 要使用一个函数,我们就得首先声明它的存在。而我们最常用的方式就是使用function语句来定义一个函数,如: 复制代码 代码如下: function abc(){ // code to process } function abc(){ // code to process } 当然,你的函数也可以是带参数的,甚至是带返回值的。 view plaincopy to clipboardprint? function abc(x,y){ return x+y; } function abc(x,y){ return x+y; }
但是,无论你怎么去定义你的函数,JS解释器都会把它翻译成一个Function对象。例如,你在定义上面的其中一个例子的函数号,再输入如下代码: alert(typeof abc);// "function" 你的浏览器就会弹出提示框,提示你abc是一个Function对象。那么Function对象究竟是什么呢? Function 对象 Function对象是JavaScript里面的固有对象,所有的函数实际上都是一个Function对象。关于这个方面的讨论,我们留到下一个专题节。我们先看看,Function对象能不能直接运用构造函数创建一个新的函数呢?答案是肯定的。例如: 复制代码 代码如下: var abc = new Function("x","y","return x*y;"); alert(abc(2,3)); // "6" var abc = new Function("x","y","return x*y;"); alert(abc(2,3)); // "6"
相信大家现在对如何声明一个函数应该是有所了解了。那么什么才是匿名函数呢? 声明匿名函数 顾名思义,匿名函数就是没有实际名字的函数。例如,我们把上面的例子中,函数的名字去掉,再判断一下他是不是一个函数: 复制代码 代码如下: 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对象,换言之,他们都是函数,但是他们都有一个特点——没有名字。所以我们把他们称作“匿名函数”。然而,正因为他们没有“名字”,我们也没有办法找到他们。这就引申了如何去调用一个匿名函数的问题了。 匿名函数的调用 要调用一个函数,我们必须要有方法定位它,引用它。所以,我们会需要帮它找一个名字。例如: 复制代码 代码如下: var abc=function(x,y){ return x+y; } alert(abc(2,3)); // "5" var abc=function(x,y){ return x+y; } alert(abc(2,3)); // "5"
上面的操作其实就等于换个方式去定义函数,这种用法是我们比较频繁遇到的。例如我们在设定一个DOM元素事件处理函数的时候,我们通常都不会为他们定名字,而是赋予它的对应事件引用一个匿名函数。 对匿名函数的调用其实还有一种做法,也就是我们看到的jQuery片段——使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表)。我们再看一下以下例子: 复制代码 代码如下: 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对象。因此,小括号对加上匿名函数就如同有名字的函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会实现普通函数的调用形式。 不知道以上的文字表述大家能不能看明白,如果还是理解不了的话,再看一下以下的代码试试吧。 复制代码 代码如下: var abc=function(x,y){return x+y;};// 把匿名函数对象赋给abc // abc的constructor就和匿名函数的constructor一样了。也就是说,两个函数的实现是一样的。 alert((abc).constructor==(function(x,y){return x+y;}).constructor); var abc=function(x,y){return x+y;};// 把匿名函数对象赋给abc // abc的constructor就和匿名函数的constructor一样了。也就是说,两个函数的实现是一样的。 alert((abc).constructor==(function(x,y){return x+y;}).constructor);
PS:constructor是指创建对象的函数。也就是函数对象所代表的函数体。 总之,将其(被小括号包含的匿名函数)理解为括号表达式返回的函数对象,然后就可以对这个函数对象作正常的参数列表调用了。(前面这里犯了个错 误,只有函数表达式还是不能直接调用函数的,去掉匿名函数括号必须要伴随将表达式赋值。也就是(function(){alert(1)})()应该是与 a=function(){alert(1)}()等价,不能连a=都去掉。) 闭包 闭包是什么?闭包是指某种程序语言中的代码块允许一级函数存在并且在一级函数中所定义的自由变量能不被释放,直到一级函数被释放前,一级函数外也能应用这些未释放的自由变量。 怎样?看得一头冒汗吧……没事,我也是(虽然是我是了解的,只是表达能力的问题)。让我们换个更加简单的方法说明:闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作搬在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止,其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。 不知道这么再解释后会否更加清晰,如果还是不明白,那么我们再简化一下:闭包,其实就是指程序语言中能让代码调用已运行的函数中所定义的局部变量。 现在我们看一个例子: 复制代码 代码如下: 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里的什么特性?那么它只是匿名函数与匿名函数的调用而已。但是,它 隐含了闭包的特性,并且随时可以实现闭包应用。
|
分享到:
相关推荐
在JavaScript中,定义函数主要有三种方式:函数关键字(function)语句定义、函数字面量(Function Literals)和Function()构造函数。函数字面量和Function()构造函数定义的函数可以没有名称,也就是我们说的匿名...
JavaScript中的匿名函数是一种没有明确标识符的函数表达式,它可以在需要时被立即执行或作为其他数据结构的一部分使用。在JavaScript中,函数是第一类对象,这意味着它们可以被赋值给变量、作为参数传递和作为其他...
### JavaScript自执行匿名函数(function() { })()的原理解析 #### 概述 JavaScript作为一种广泛应用于Web开发的脚本语言,其灵活性和强大功能在很大程度上归功于其独特的特性之一——自执行匿名函数(Immediately ...
在JavaScript中,匿名函数、函数直接量和闭包是三种非常重要的概念,它们在编程实践中有着广泛的应用。让我们逐一深入探讨这些概念。 1. **匿名函数**: 匿名函数是指没有名字的函数,通常作为表达式的一部分存在...
在JavaScript中,我们可以使用IIFE(Immediately Invoked Function Expression,即立即调用的函数表达式)来实现匿名函数的执行。IIFE是JavaScript中一个常见的编程技巧,它的结构就是标题和描述中提到的格式: ```...
### JavaScript中匿名函数的创建与调用方法分析 #### 一、概述 在JavaScript中,函数是一等公民,这意味着函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。这种灵活性使得JavaScript中的函数非常强大...
在JavaScript中,我们可以使用`function`关键字来定义一个函数。基本语法如下: ```javascript function 函数名(参数1, 参数2, ...){ // 函数体,执行的代码 } ``` 例如,创建一个简单的函数`sayHello`,它接受一...
调用该函数时,只需使用函数名后跟括号,并传入相应的参数即可,如`sum(1, 2)`。 #### 向函数传递参数 函数可以接受任意数量的参数,通过逗号分隔。如果提供的参数数量少于定义的数量,未传入的参数默认为`...
JavaScript中的匿名函数和闭包是两个非常重要的概念,它们在函数式编程和模块化开发中起着关键作用。 首先,让我们来理解匿名函数。匿名函数,顾名思义,是没有名称的函数。在JavaScript中,我们可以直接定义一个不...
### JavaScript匿名函数调用示例解析 #### 一、引言 在JavaScript编程语言中,函数是一等公民,这意味着函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。这种灵活性使得JavaScript中的函数非常强大。...
正确的匿名函数写法应该使用括号将函数声明括起来,如:(function(){...}())。这是因为括号内的内容被解释为表达式,而表达式可以是匿名的。 方法一:函数字面量(FunctionLiteral)。这是创建匿名函数最常用的一种...
以上就是JavaScript匿名函数实例分析的知识点。通过实例的讲解,我们了解了匿名函数的定义、用法及注意事项。掌握这些概念对编写高质量的JavaScript代码非常重要。对于希望深入学习JavaScript的开发者来说,理解和...
代码如下: (function(){ //这里忽略jQuery所有实现 })();...当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来!真神奇哦! 嘿嘿!胡闹到此为止。在这一节,我们碰到
在JavaScript中,匿名函数是一种没有名称的函数表达式,通常用于一次性任务或者作为参数传递。它们在各种上下文中有着广泛的应用,如事件处理、回调函数等。本篇文章将详细讲解14种不同的匿名函数调用方法。 1. **...
匿名函数就是没有实际名字的函数。...//据说效率最高,Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值。 !function(){ alert(‘!water’); }(); //运算符+匿名函数调用 (f
JavaScript中的匿名函数与闭包是两个非常重要的概念,它们在函数式编程以及处理变量作用域方面发挥着关键作用。理解这两个概念对于深入学习JavaScript至关重要。 首先,匿名函数,正如其名,是没有名称的函数,通常...
本文将详细阐述JavaScript匿名函数的定义、不同定义方式、与Function构造函数的区别,以及匿名函数的常见使用模式和应用场景。 **一、匿名函数的定义** 在JavaScript中,匿名函数可以通过以下三种方式创建: 1. *...
**两种调用函数的方式** 在JavaScript中,可以使用两种模式来调用函数:标准调用和括号调用。标准调用如 `func(a, b)`,而括号调用如 `(func)(a, b)`。括号调用常用于延迟执行或组合函数。 **“短路”条件调用** ...
函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途。匿名函数指没有指定函数名或指针的函数,自执行匿名函数只是其中一种,下文中称这种函数为:自执行函数 下面是一个最常见的自执行函数: // ...