前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript自调函数

javascript自调函数

作者头像
Bob.Chen
发布2018-04-27 10:56:56
1.3K0
发布2018-04-27 10:56:56
举报

JavaScript中匿名函数一种非常常见的用法就是自调函数,这种函数可以在定义之后自行调用。

自调函数常见形式是:

(function(){
    alert("foo");
})()

光看这个形式,可能会让人以为是在函数体前后包个括号,然后后面通过括号运算符来立即调用函数,形式上说是对的,但是为什么要给函数包个括号?下面我们就来重新认识一下自调函数。 要理解自调函数,首先我们要理解两个概念

函数声明

函数声明通常由一下几部分组成:

  • function子句
  • 函数名称
  • 函数的参数
  • 函数体
  • return子句,默认返回值为undefined。

例子:

function foo(a,b) {
    return a+b;
}

函数表达式

函数声明容易理解,函数表达式就陌生多了。其实,这里说的函数表达式,顾名思义就是一种表达式,内容是函数。表达式就是那些个加减乘除之类的。

比如说下面这个例子:

var foo = function (a,b) {
            return a+b;
          };

例子中,创建了一个匿名函数,然后把这个匿名函数的引用给了foo这个变量。 严格来说,这个例子不完全是函数表达式,去除var foo之后,剩下的就是一个函数表达式。

上面的例子要如何调用函数?很明显foo(1,2)就可以了,之前说过foo不过是那个匿名函数的引用,对foo使用括号运算符就可以调用这个匿名函数了。

既然如此,是不是也可以这样调用:

d = function (a,b) {
    return a+b;
}(1,2)

这里变量d的值是3,因为此处等号是个二元运算符,所以看的可能不是太清楚,可以尝试改成如下形式:

+ function (a,b) {
        return a+b;
    }(1,2)

控制台中运行会输出3,这就是一个自调函数。

重新认识自调函数

分清楚函数声明和函数表达式之后,我们来重新认识自调函数。 先看几个例子:

(function(a){
    console.log(a);   //123
})(123);

(function(a){
    console.log(a);   //123
}(123));

! function(a){
    console.log(a);   //123
}(123);

+ function(a){
    console.log(a);   //1234
}(123);

- function(a){
    console.log(a);   //123
}(123);

void function(a){
    console.log(a);   //123
}(123)

可以看出,要让匿名函数自调用,首先要把匿名函数变成函数表达式,而不能是函数声明。 而把函数声明变成函数表达式的方法就是在function关键字前面加点什么东西,例如括号,+,-,!,void,=,逗号,~……告诉js解析引擎,这个是一个函数表达式,可以通过()运算符来执行。

而加()是最安全的做法,因为加减号会影响返回值,而void会让返回值为undefined,所以括号用的最广泛,但我们要知道除了括号,别的也能实现自调函数。

自调用函数解决setTimeout传参数

有时候我们需要循环设置setTimeout,并且每次执行的函数的参数还不一样,这个时候就是我们的自调函数大显身手的时候了:

var i = 0, tmp = [1,2,3];
for(i,len=tmp.length;i<len;i++) {
    setTimeout(
        (function(txt){
          return function(){
            console.log(txt)
          }
        })(tmp[i]),
    1000*i);
}

控制台执行,可以看到依次打印出1,2,3 理解一下上面setTimeout的执行:

  1. setTimeout里面把(function(){})()当成函数表达式执行,返回了一个匿名函数的引用;
  2. 当延时结束的时候,由js解释器来执行这个函数引用。

这里要注意,返回的是函数的引用,不要单纯的理解为字符串的传递。

参考资料

http://dengo.org/archives/1004 https://segmentfault.com/q/1010000002867883

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数声明
  • 函数表达式
  • 重新认识自调函数
  • 自调用函数解决setTimeout传参数
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档