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代码, ...
随机推荐
- C# IO操作(三)文件编码
在.net环境下新建一个文本文件(所谓文本文件就是直接可以用记事本打开的文件,直接保存字符串)和在系统中新建一个文本文件的编码是不一样的,.net默认采用UTF-8,而中文操作系统采用的是ANSI.如 ...
- 在Xcode6中找回失去的模板
[Add]2014.07.27 添加OC category.protocol模板 Xcode 6从beta 3开始在创建新项目窗口中移除了“Empty Application”,如下: 其他选项很不幸 ...
- 检测PC端和移动端的方法总结
正在苦逼的实习中,昨天公司让做一个页面,涉及到检测终端的问题,如果是手机设备,就跳转到指定的网页上,以前写响应式布局只要用@media screen来实现布局的差异化适应,但是现在不仅仅是布局,还要针 ...
- 2016/7/7 自定义函数copy
题目:输入整数n(n<=10000),表示接下来将会输入n个实数,将这n个实数存入数组a中.请定义一个数组拷贝函数将数组a中的n个数拷贝到数组b中. 分析: (1)输入n,再输入n个实数存入数组 ...
- c++ primer (5)2
第三章 1.头文件不应包含using声明,因为头文件的内容会拷贝到所有引用它的文件中去. 2.初始化string对象的方式: string s1; //默认初始化,s1是一个空串 string s2( ...
- [翻译][MVC 5 + EF 6] 6:创建更复杂的数据模型
原文:Creating a More Complex Data Model for an ASP.NET MVC Application 前面的教程中,我们使用的是由三个实体组成的简单的数据模型.在本 ...
- Oracle if else if for case
------------------游标+for+if else if DECLARE cursor s_cursor is SELECT * from emp;--定义游标 begin for r ...
- mysql 之权限介绍
转自:http://tech.it168.com/a2010/0114/837/000000837456_all.shtml 一.MySQL授权表概述首先从全局开始,如果全局的是允许的,即在 user ...
- 使用jQuery.FileUpload和Backload自定义控制器上传多个文件
当需要在控制器中处理除了文件的其他表单字段,执行控制器独有的业务逻辑......等等,这时候我们可以自定义控制器. 通过继承BackloadController □ 思路 BackloadContro ...
- js 数字,金额 用逗号 隔开。数字格式化
例如: 12345格式化为12,345.00 12345.6格式化为12,345.60 12345.67格式化为 12,345.67 只留两位小数. 回来后写了个格式化函数.可以控制小数位数,自动四舍 ...