自调用函数

自调用函数(self-invoking funciton)就是函数定义完之后会立即运行的函数. 最常见的写法是:

(function() {
// function body...
}());
// or
(function() {
// function body...
})();

自调用函数的另一种写法

不过最近看某个库的源代码(暂时忘了是哪个了=,.=)时发现有如下写法:

+function() {
// function body
}();

感到神奇, 于是SO了一下, 原来这是另一种自调用函数的写法.

+号使得js解释器认为它现在在处理的是一个表达式, 而非函数定义. 如果不写这个+号, 解释器会按照函数定义去处理, 并认为后面的()是语法错误.

其实除了+号, -, !, ~以及其他一元操作符都可以产生相同的效果.

与要在用()把函数包起来的常用写法相比, 这种写法的好处(也许)就是只要在前面加个+就行了, 更省事儿. 当然, 最后的();是一定不能少的.

需要注意的问题

主要注意的是, 一定不能省略自调用函数前面赋值语句的;.

如果自调用函数前面是函数定义, 一切正常:

function x() { console.log(1); } +function () { console.log(2); }();
// 2

但是如果它前面是个赋值语句, 你的代码非常容易出bug, 即使是用()包裹自调用函数也不行.

var s = {}; s.a = function() { console.log(1); } + function() { s.a(); }();
// Uncaught TypeError: s.a is not a function(…)
var s = {}; s.a = function() { console.log(1); } (function() { s.a(); }());
// Uncaught TypeError: s.a is not a function(…)
var a = function() { console.log(1); } + function() { console.log(2); }();
// 2
// a is “function () { console.log(1); }undefined”
var a = function() { console.log(1); } (function() { console.log(2); }());
// 2 1
// a is `undefined`!!
var a = function() { console.log(1); } (+ function() { console.log(2); }());
// 2 1
// a is `undefined`!!

我以前曾经遇到这个bug, 但是并不知道发生了什么, 只是很奇怪为什么自调用函数前面的那个函数会自动执行... 后来我无奈用了下面这种弱鸡的形式

function init() {
// function body
}
init();

正确的做法应该是:

var x = function() {
console.log(1);
}; // <---------------- here! DO NOT omit this semicolon!
+ function() {
console.log(2);
}();

我还听说有minify之前运行得好好的, minify之后就出bug, 也是因为少了;.

综上, 在每句赋值语句后面加上;号是一个很重要的好习惯!

自调用函数前面的;

2016/4/14更新

今天瞟了一眼platform.js的源代码, 看到最外层是

;(function() {
// function body...
}.call(this));

SO了一下, 这是一种更加保险的方式.

假设两个文件的内容分别是:

// File A
(function(){console.log(1);})()
// File B
(function(){console.log(2);})()

那么这两个文件打包到一起就会报错

(function(){console.log(1);})()(function(){console.log(2);})()
// Uncaught TypeError: (intermediate value)(...) is not a function(…)

当然, 这个错误也是由于两个文件中不好的代码习惯导致的--就是最后没有加;. 而在(function...前面写上;就可以100%确保自调用函数的正常执行.

参考

  1. Does omitting semicolons affect performance in JavaScript?
  2. Why should I use a semicolon after every function in javascript?

JavaScript中的自调用函数的更多相关文章

  1. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  2. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  3. 使用Ajax在javascript中调用后台C#函数

    使用Ajax在javascript中调用后台C#函数 最近一段时间在紧跟一个网站的项目,数据库中用户表的UserName要求是唯一的,所以当用户选定一个用户名进行注册时要首先检查该用户名是否已被占用, ...

  4. 在javascript中关于变量与函数的提升

    在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...

  5. javascript中的立即执行函数(function(){…})()

    javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...

  6. 深入理解javascript中的立即执行函数

    这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...

  7. JavaScript中的内置函数

    JavaScript中的内置函数 制作人:全心全意 在使用JavaScript语言时,除了可以自定义函数之外,还可以使用JavaScript的内置函数,这些内置函数是由JavaScript语言自身提供 ...

  8. JavaScript 中对变量和函数声明提前的演示样例

    如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...

  9. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

随机推荐

  1. MongoDB的主从复制和副本集

    mongoDB的两个特性主从复制和副本集,实现了数据的同步备份 一.主从复制 主从复制是一个简单的数据库同步备份的集群技术.例如主服务器宕机了,可以直接使用从服务器,主服务器恢复后在进行同步,保证了业 ...

  2. mysqld-nt: Out of memory (Needed 1677720 bytes)解决方法

    http://www.jb51.net/article/58726.htm 今天发现网站有点慢,发现mysql日志中提示mysqld-nt: Out of memory (Needed 1677720 ...

  3. JavaScript基础-面向对象编程<1>

    1.1 函数与对象  1.定义函数的方式定义类 定义类的方法: function class1(){ //类成员的定义及构造函数部分 } class1既是一个函数,也是一个类. 使用 new 操作符获 ...

  4. java守护线程(后台线程)

    /*1.让各个对象或类相互灵活交流2.两个线程都冻结了,就不能唤醒了,因为根据代码要一个线程活着才能执行唤醒操作,就像玩木游戏3.中断状态就是冻结状态4.当主线程退出的时候,里面的两个线程都处于冻结状 ...

  5. 7zip self-extracted executable: To extract file to specific directory

    1) Install 7-zip (7zS.sfx will be installed to C:\Program Files\7-Zip): http://7zsfx.solta.ru/en/ 2) ...

  6. Fire Net

    Fire Net Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Subm ...

  7. PHP扩展开发(1):入门

    有关PHP扩展开发的文章.博客已经很多了,比较经典的有: TIPI项目(http://www.php-internals.com/,强烈推荐) <Extending and Embedding ...

  8. 一套帮助你理解C语言的测试题(转)

    前言 原文链接:http://www.nowamagic.net/librarys/veda/detail/775 内容 在这个网站(http://stevenkobes.com/ctest.html ...

  9. yii2 用gii生成后台模块 view path描述

    view path 格式: @backend/views/refund , 注意@和/

  10. C语言到底怎么了?

    自2015年11月开始,所有C语言系列都呈现出衰落之势.在超过15年的时间里,C语言在编程语言排行榜中的占比一直有15%-20%,但今年却突然急转直下,目前占比已不足10%,且目前看来回天乏力. 那么 ...