js中匿名函数的创建与调用方法分析


Posted in Javascript onDecember 19, 2014

本文实例分析了js中匿名函数的创建与调用方法。分享给大家供大家参考。具体实现方法如下:

匿名函数就是没有名字的函数了,也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值,很多新手朋友对于匿名函数不了解。这里就来分析一下。

function 函数名(参数列表){函数体;}

如果是创建匿名函数,那就应该是:
function(){函数体;}

因为是匿名函数,所以一般也不会有参数传给他。

为什么要创建匿名函数呢?在什么情况下会使用到匿名函数。匿名函数主要有两种常用的场景,一是回调函数,二是直接执行函数。

回调函数,像ajax的异步操作,就需要回调函数。这里就不详解。关于直接执行函数,我看一个例子就明白了:

<script language="javascript">

var a = "a";

(function(){

    var a="b";

    alert(a);

})();

alert(a);

</script>

在上面这段代码中,会顺序输出两个alert框。第一个alert框内容为b,第二个为a。大家看到什么好处了吗?对的,使用函数直接执行可以限定变量的作用域,使不同脚本的相同变量可以得以共存。

下面,我们先初步了解一下和匿名函数相关的概念。

函数声明(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"

相信大家现在对如何声明一个函数应该是有所了解了。那么什么才是匿名函数呢?

声明匿名函数

顾名思义,匿名函数就是没有实际名字的函数。例如,我们把上面的例子中,函数的名字去掉,再判断一下他是不是一个函数:

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"

上面的操作其实就等于换个方式去定义函数,这种用法是我们比较频繁遇到的。例如我们在设定一个DOM 元素事件处理函数的时候,我们通常都不会为他们定名字,而是赋予它的对应事件引用一个匿名函数。

对匿名函数的调用其实还有一种做法,也就是我们看到的jQuery 片段—— 使用() 将匿名函数括起来,然后后面再加一对小括号(包含参数列表)。我们再看一下以下例子:

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);

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” 未定义!

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

以我的理解来说吧。是否应用了闭包特性,必须确定该段代码有没有最重要的要素:未销毁的局部变量。那么很显然,没有任何实现的匿名函数不可能应用了闭包特性。但如果匿名函数里面有实现呢?那也还得确定它的实现中有没有 用到那些未销毁的局部变量。所以如果问你那个开篇中的jQuery 代码片段是应用了JS 里的什么特性?那么它只是匿名函数与匿名函数的调用而已。但是,它 隐含了闭包的特性,并且随时可以实现闭包应用。

最常见的用法:

(function() { 

alert('water'); 

})();

当然也可以带参数:
(function(o) { 

alert(o); 

})('water');

想用匿名函数的链式调用?很简单:
(function(o) { 

alert(o); 

return arguments.callee; 

})('water')('down');

常见的匿名函数都知道了,看看不常见的:
~(function(){ 

alert('water'); 

})();//写法有点酷~

 

void function(){ 

alert('water'); 

}();//据说效率最高~

 

+function(){ 

alert('water'); 

}();

 

-function(){ 

alert('water'); 

}();

 

~function(){ 

alert('water'); 

}();

 

!function(){ 

alert('water'); 

}();

 

(function(){ 

alert('water'); 

}());//有点强制执行的味道~

希望本文所述对大家的javascript程序设计有所帮助。

Javascript 相关文章推荐
javascript prototype,executing,context,closure
Dec 24 Javascript
JQUBAR1.1 jQuery 柱状图插件发布
Nov 28 Javascript
浅谈javascript实现八大排序
Apr 27 Javascript
js中不同的height, top的区别对比
Sep 24 Javascript
解决JavaScript数字精度丢失问题的方法
Dec 03 Javascript
jquery html动态添加的元素绑定事件详解
May 24 Javascript
Bootstrap布局方式详解
May 27 Javascript
自动适应iframe右边的高度
Dec 22 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
Jun 08 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
Jul 10 Javascript
React props和state属性的具体使用方法
Apr 12 Javascript
原生js实现移动小球(碰撞检测)
Dec 17 Javascript
浅谈Javascript中匀速运动的停止条件
Dec 19 #Javascript
浅谈Javascript如何实现匀速运动
Dec 19 #Javascript
Javascript添加监听与删除监听用法详解
Dec 19 #Javascript
Javascript 实现图片无缝滚动
Dec 19 #Javascript
使用JavaScript获取地址栏参数的方法
Dec 19 #Javascript
JS获取各种宽度、高度的简单介绍
Dec 19 #Javascript
JQuery右键菜单插件ContextMenu使用指南
Dec 19 #Javascript
You might like
提高PHP编程效率 引入缓存机制提升性能
2010/02/15 PHP
php在文件指定行中写入代码的方法
2012/05/23 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
2017/08/18 PHP
发现的以前不知道的函数
2006/09/19 Javascript
用javascript作一个通用向导说明
2011/08/30 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
2012/09/14 Javascript
封装html的select标签的js操作实例
2013/07/02 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
2015/10/23 Javascript
Bootstrap零基础入门教程(二)
2016/07/18 Javascript
AngularJS动态生成div的ID源码解析
2016/08/29 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
详解Vue快速零配置的打包工具——parcel
2018/01/16 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
JS一次前端面试经历记录
2020/03/19 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
[01:37]全新的一集《真视界》——TI7总决赛
2017/09/21 DOTA
dataframe设置两个条件取值的实例
2018/04/12 Python
python实现kNN算法识别手写体数字的示例代码
2019/08/16 Python
Python计算两个矩形重合面积代码实例
2019/09/16 Python
pymysql的简单封装代码实例
2020/01/08 Python
python爬虫容易学吗
2020/06/02 Python
Python中的Cookie模块如何使用
2020/06/04 Python
python 识别登录验证码图片功能的实现代码(完整代码)
2020/07/03 Python
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
波兰在线杂货店:Polski Koszyk
2019/11/02 全球购物
Bath & Body Works阿联酋:在线购买沐浴和身体用品
2021/02/27 全球购物
面试求职的个人自我评价
2013/11/16 职场文书
计算机维护专业推荐信
2014/02/27 职场文书
就职演讲稿范文
2014/05/19 职场文书
国庆节促销广告语2014
2014/09/19 职场文书
2014年向国旗敬礼活动方案
2014/09/27 职场文书
合同权益转让协议书模板
2014/11/18 职场文书
三好学生事迹材料
2014/12/24 职场文书
活动简报范文
2015/07/22 职场文书
2016年感恩教师节校园广播稿
2015/12/18 职场文书
动画「半妖的夜叉姬」新BD特典图公开
2022/03/22 日漫