JavaScript中的自调用函数
自调用函数
自调用函数(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%确保自调用函数的正常执行.
参考
- Does omitting semicolons affect performance in JavaScript?
- Why should I use a semicolon after every function in javascript?
JavaScript中的自调用函数的更多相关文章
- [转]Javascript中的自执行函数表达式
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- 使用Ajax在javascript中调用后台C#函数
使用Ajax在javascript中调用后台C#函数 最近一段时间在紧跟一个网站的项目,数据库中用户表的UserName要求是唯一的,所以当用户选定一个用户名进行注册时要首先检查该用户名是否已被占用, ...
- 在javascript中关于变量与函数的提升
在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...
- javascript中的立即执行函数(function(){…})()
javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...
- 深入理解javascript中的立即执行函数
这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...
- JavaScript中的内置函数
JavaScript中的内置函数 制作人:全心全意 在使用JavaScript语言时,除了可以自定义函数之外,还可以使用JavaScript的内置函数,这些内置函数是由JavaScript语言自身提供 ...
- JavaScript 中对变量和函数声明提前的演示样例
如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...
- javascript中的this与函数讲解
前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...
随机推荐
- Sqlserver 安装
安装环境: SqlServer版本:Sql Server 2008 (安装包您应该已有准备) =============以下开始安装,多图,基本软件操作不做太多说明,注意查看图片=========== ...
- Extjs4使用iframe注意事项
"video" : { render : function(panel, eOpts) { // 因为iframe在video // panel渲染的时候就已经完全移动到video ...
- 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...
- UITabBar - 深度解剖
for (UIView *tabbarbutton in self.subviews) { // NSLog(@"%@",tabbarbutton); ...
- vs 2010 Cannot find or open the PDB file
打开VS2010:工具-->选项-->>调试-->符号接下来就是选择Microsoft,然后确认 接着随便编译一个程序,过程会灰常的慢. 看到此目录下符号缓存了吗?C:\Us ...
- bzoj 1096: [ZJOI2007]仓库建设
dp是很好想的了,关键是数据太大,普通dp肯定超时,所以一定有用某种优化,dp优化也就那么几种,这道题用的是斜率优化,先写出普通的状态转移方程: dp[i] = min{ dp[j] + Σ ( p ...
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- 使用curl获取网站的http的状态码
发布:thebaby 来源:net [大 中 小] 本文分享一例shell脚本,一个使用curl命令获取网站的httpd状态码的例子,有需要的朋友参考下.本文转自:http://www.j ...
- Java小例子——穷举质数,求平方和,求质因子。
求平方和 public static void main(String[] args) throws IOException { int n; String s; BufferedReader buf ...
- oracle忘记用户密码
在cmd命令行下输入sqlplus / as sysdba alter user system identified by abc; 就可以将system用户的密码改成abc了. alter user ...