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代码, ...
随机推荐
- Microsoft Word 的键盘快捷方式
Microsoft Word 的键盘快捷方式 全部显示 全部隐藏 本帮助文章中描述的键盘快捷方式适用于美式键盘布局.其他键盘布局的键可能与美式键盘上的键 不完全对应. 注释 本文不介绍如何为宏或自 ...
- 学习笔记4_ServletContext(重要整个Web应用的动态资源之间共享数据)
ServletContext(重要) 一个项目只有一个ServletContext对象! 我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据! 与天地同寿!! ...
- 2016/01/19 javascript学习笔记-name属性
1. name属性只在少数html元素中有效:包括表单.表单元素.<iframe>和<img>元素. 基于name属性的值选取html元素,可以使用document对象的get ...
- Linux用户级线程和内核级线程区别
1.内核级线程: (1)线程的创建.撤销和切换等,都需要内核直接实现,即内核了解每一个作为可调度实体的线程.(2)这些线程可以在全系统内进行资源的竞争.(3)内核空间内为每一个内核支持线程设置了一个线 ...
- OpenJudge / Poj 1044 Date bugs C++
链接地址: Poj:http://poj.org/problem?id=1044 OpenJudge:http://bailian.openjudge.cn/practice/1044/ 题目: 总时 ...
- 24种设计模式--中介者模式【Mediator Pattern】
各位好,大家都是来自五湖四海,都要生存,于是都找了个靠山——公司,给你发薪水的地方,那公司就要想尽办法盈利赚钱,盈利方法则不尽相同,但是作为公司都有相同三个环节:采购.销售和库存,这个怎么说呢?比如一 ...
- Openstack安装
作者:陈沙克 Openstack发展很猛,很多朋友都很认同,2013年,会很好的解决OpenStack部署的问题,让安装,配置变得更加简单易用. 很多公司都投入人力去做这个,新浪也计划做一个Opens ...
- js搜索框 js仿百度搜索 js下拉框 jQuery.Autocomplete使用
做了一个网站,需要根据文本框的输入模糊搜索数据库内容给出提示供用户选择,就找到了jQuery.Autocomplete 效果如下图: 该插件托管在github上,具体地址:https://github ...
- C# 读取快捷方式指向的文件
C# 读取快捷方式指向的文件 [Flags()] public enum SLR_FLAGS { SLR_NO_UI = 0x1, SLR_ANY_MATCH = 0x2, SLR_UPDATE = ...
- Cassandra1.2文档学习(5)—— Snitch
参考资料:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...