0

0

js的(function(){xxx})()使用详解

php中世界最好的语言

php中世界最好的语言

发布时间:2018-06-04 17:35:48

|

3312人浏览过

|

来源于php中文网

原创

这次给大家带来js的(function(){xxx})()使用详解,js的(function(){xxx})()使用的注意事项有哪些,下面就是实战案例,一起来看一下。

js中(function(){xxx})();写法解析

自执行匿名函数

  • 常见格式:(function() { /* code */ })();

  • 解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数

  • 作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。

总结一下,执行函数的作用主要为 匿名 和 自动执行,代码在被解释时就已经在运行了。

其他写法

(function () { /* code */ } ()); 
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();

function与感叹号

最近有空可以让我静下心来看看各种代码,function与感叹号的频繁出现,让我回想起2个月前我回杭州最后参加团队会议的时候,@西子剑影抛出的一样的问题:如果在function之前加上感叹号 (!) 会怎么样?比如下面的代码:

!function(){alert('iifksp')}()        // true

在控制台运行后得到的值时true,为什么是true这很容易理解,因为这个匿名函数没有返回值,默认返回的就是undefined,求反的结果很自然的就是true。所以问题并不在于结果值,而是在于,为什么求反操作能够让一个匿名函数的自调变的合法?

平时我们可能对添加括号来调用匿名函数的方式更为习惯:

(function(){alert('iifksp')})()        // true

或者:

(function(){alert('iifksp')}())        // true

虽然上述两者括号的位置不同,不过效果完全一样。

那么,是什么好处使得为数不少的人对这种叹号的方式情有独钟?如果只是为了节约一个字符未免太没有必要了,这样算来即使一个100K的库恐怕也节省不了多少空间。既然不是空间,那么就是说也许还有时间上的考量,事实很难说清,文章的最后有提到性能。

回到核心问题,为什么能这么做?甚至更为核心的问题是,为什么必须这么做?

其实无论是括号,还是感叹号,让整个语句合法做的事情只有一件,就是让一个函数声明语句变成了一个表达式。

function a(){alert('iifksp')}        // undefined

这是一个函数声明,如果在这么一个声明后直接加上括号调用,解析器自然不会理解而报错:

function a(){alert('iifksp')}()        // SyntaxError: unexpected_token

因为这样的代码混淆了函数声明和函数调用,以这种方式声明的函数 a,就应该以 a(); 的方式调用。

但是括号则不同,它将一个函数声明转化成了一个表达式,解析器不再以函数声明的方式处理函数a,而是作为一个函数表达式处理,也因此只有在程序执行到函数a时它才能被访问。

所以,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。比如:

var i = function(){return 10}();        // undefined  1 && function(){return true}();        // true  1, function(){alert('iifksp')}();        // undefined

赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的:

!function(){alert('iifksp')}()        // true+function(){alert('iifksp')}()        // NaN-function(){alert('iifksp')}()        // NaN~function(){alert('iifksp')}()        // -1

甚至下面这些关键字,都能很好的工作:

void function(){alert('iifksp')}()        // undefined  new function(){alert('iifksp')}()        // Object  delete function(){alert('iifksp')}()        // true

最后,括号做的事情也是一样的,消除歧义才是它真正的工作,而不是把函数作为一个整体,所以无论括号括在声明上还是把整个函数都括在里面,都是合法的:

(function(){alert('iifksp')})()        // undefined(function(){alert('iifksp')}())        // undefined

说了这么多,实则在说的一些都是最为基础的概念——语句,表达式,表达式语句,这些概念如同指针与指针变量一样容易产生混淆。虽然这种混淆对编程无表征影响,但却是一块绊脚石随时可能因为它而头破血流。

最后讨论下性能。我在jsperf上简单建立了一个测试:http://jsperf.com/js-funcion-expression-speed ,可以用不同浏览器访问,运行测试查看结果。我也同时将结果罗列如下表所示(由于我比较穷,测试配置有点丢人不过那也没办法:奔腾双核1.4G,2G内存,win7企业版):

Option Code Ops/sec
Chrome 13 Firefox 6 IE9 Safari 5
! !function(){;}() 3,773,196 10,975,198 572,694 2,810,197
+ +function(){;}() 21,553,847 12,135,960 572,694 1,812,238
- -function(){;}() 21,553,847 12,135,960 572,694 1,864,155
~ ~function(){;}() 3,551,136 3,651,652 572,694 1,876,002
(1) (function(){;})() 3,914,953 12,135,960 572,694 3,025,608
(2) (function(){;}()) 4,075,201 12,135,960 572,694 3,025,608
void void function(){;}() 4,030,756 12,135,960 572,694 3,025,608
new new function(){;}() 619,606 299,100 407,104 816,903
delete delete function(){;}() 4,816,225 12,135,960 572,694 2,693,524
= var i = function(){;}() 4,984,774 12,135,960 565,982 2,602,630
&& 1 && function(){;}() 5,307,200 4,393,486 572,694 2,565,645
|| 0 || function(){;}() 5,000,000 4,406,035 572,694 2,490,128
& 1 & function(){;}() 4,918,209 12,135,960 572,694 1,705,551
| 1 | function(){;}() 4,859,802 12,135,960 572,694 1,612,372
^ 1 ^ function(){;}() 4,654,916 12,135,960 572,694 1,579,778
, 1, function(){;}() 4,878,193 12,135,960 572,694 2,281,186

可见不同的方式产生的结果并不相同,而且,差别很大,因浏览器而异。

但我们还是可以从中找出很多共性:new方法永远最慢——这也是理所当然的。其它方面很多差距其实不大,但有一点可以肯定的是,感叹号并非最为理想的选择。反观传统的括号,在测试里表现始终很快,在大多数情况下比感叹号更快——所以平时我们常用的方式毫无问题,甚至可以说是最优的。加减号在chrome表现惊人,而且在其他浏览器下也普遍很快,相比感叹号效果更好。

当然这只是个简单测试,不能说明问题。但有些结论是有意义的:括号和加减号最优。

但是为什么这么多开发者钟情于感叹号?我觉得这只是一个习惯问题,它们之间的优劣完全可以忽略。一旦习惯了一种代码风格,那么这种约定会使得程序从混乱变得可读。如果习惯了感叹号,我不得不承认,它比括号有更好的可读性。我不用在阅读时留意括号的匹配,也不用在编写时粗心遗忘——

当我也这么干然后嚷嚷着这居然又节省了一个字符而沾沾自喜的时候,却忘了自己仓皇翻出一本卷边的C语言教科书的窘迫和荒唐......任何人都有忘记的时候,当再捡起来的时候,捡起的就已经不单单是忘掉的东西了。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

php商城系统
php商城系统

PHP商城系统是国内功能优秀的网上商城系统,同时也是一个商业的PHP开发框架,有多套免费模版,强大的后台管理功能,专业的网上商城系统解决方案,快速建设网上购物商城、数码商城、手机商城、办公用品商城等网站。 php商城系统v3.0 rc6升级 1、主要修复用户使用中出现的js未加载完报错问题,后台整改、以及后台栏目的全新部署、更利于用户体验。 2、扩展出,更多系统内部的功能,以便用户能够迅速找到需

下载

JS框架库使用案例详解

怎样使用原生js做出满天星效果

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

43

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

35

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

41

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

204

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

9

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

8

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 1.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号