!function(){}()

http://my.oschina.net/u/2331760/blog/468672?p={{currentPage+1}}

 

( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目 的,后来发现加括号的原因并非如此。要理解立即执行函数,需要先理解一些函数的基本概念。

 

函数声明、函数表达式、匿名函数

 

函数声明:function fnName () {…};使用function关键字声明一个函数,再指定一个函数名,叫函数声明。

 

函数表达式 var fnName = function () {…};使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。

 

匿名函数:function () {}; 使用function关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。

 

函数声明和函数表达式不同之处在于,一、Javascript引擎在解析javascript代码时会‘函数声明提升’(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函 数表达式,二、函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。以下是两者差别的两个例子。

实例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fnName();
function fnName(){
    ...
}//正常,因为‘提升’了函数声明,函数调用可在函数声明之前
  
fnName();
var fnName=function(){
    ...
}//报错,变量fnName还未保存对函数的引用,函数调用必须在函数表达式之后
var fnName=function(){
    alert('Hello World');
}();//函数表达式后面加括号,当javascript引擎解析到此处时能立即调用函数
function fnName(){
    alert('Hello World');
}();//不会报错,但是javascript引擎只解析函数声明,忽略后面的括号,函数声明不会被调用
function(){
    console.log('Hello World');    
}();//语法错误,虽然匿名函数属于函数表达式,但是未进行赋值操作,
//所以javascript引擎将开头的function关键字当做函数声明,报错:要求需要一个函数名

 

在理解了一些函数基本概念后,回头看看( function(){…} )()和( function (){…} () )这两种立即执行函数的写法,最初我以为是一个括号包裹匿名函数,并后面加个括号立即调用函数,当时不知道为什么要加括号,后来明白,要在函数体后面加括 号就能立即调用,则这个函数必须是函数表达式,不能是函数声明。

 

实例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(function(a){
    console.log(a);   //firebug输出123,使用()运算符
})(123);
  
(function(a){
    console.log(a);   //firebug输出1234,使用()运算符
}(1234));
  
!function(a){
    console.log(a);   //firebug输出12345,使用!运算符
}(12345);
  
+function(a){
    console.log(a);   //firebug输出123456,使用+运算符
}(123456);
  
-function(a){
    console.log(a);   //firebug输出1234567,使用-运算符
}(1234567);
  
var fn=function(a){
    console.log(a);   //firebug输出12345678,使用=运算符
}(12345678)

可以看到输出结果,在function前面加!、+、 -甚至是逗号等到都可以起到函数定义后立即执行的效果,而()、!、+、-、=等运算符,都将函数声明转换成函数表达式,消除了javascript引擎 识别函数表达式和函数声明的歧义,告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。

 

加括号是最安全的做法,因为!、+、-等运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。

 

不过这样的写法有什么用呢?

 

javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能会被其他人不小心用同名的变量 给覆盖掉,根据javascript函数作用域链的特性,可以使用这种技术可以模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外 部的变量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

 

JQuery使用的就是这种方法,将JQuery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用JQuery代码时,可以达到保护JQuery内部变量的作用。

转载于:https://www.cnblogs.com/mrxiaohe/p/5234998.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

altium designer 10哪个作者写的好 。

问题截图: 博主解答: 其实这种书籍基本内容都差不多,很多都是作者来回借鉴,我们能根据自己的需要学到知识即可。

orm查询部分字段_ORM问题第2部分–查询

orm查询部分字段在我以前关于对象关系映射工具(ORM)的帖子中,我讨论了在处理当今常见的ORM(包括Hibernate)时遇到的各种问题。 其中包括与从POJO生成架构有关的问题,实际性能和不断出现的维护问题。 本质上…

新浪微博开发-添加子视图控制器设置颜色

一.添加子视图控制器 二.设置颜色 设置颜色:两种方法 一种较为繁琐,详见视频 第二种: //设置颜色 self.tabBar.tintColor UIColor.orangeColor()转载于:https://www.cnblogs.com/torrescx/p/5237142.html

linux ssh无需密码,linux下 ssh 实现无需密码的远程登陆

主机A(OpenSUSE12.1):119.78.222.95主机B (Fedora16): 202.122.25.361.主机A:生成秘钥对id_rsa和id_rsa.publinux-9juc:~ # ssh-keygen -t rsaGenerating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/id_rsa):Created directory /root/.ssh.…

Android studio的sdk tools下没有LLDB的解决办法

粉丝提问: 博主解答: 解决办法: 点击setting--》plugins--》找到“Android Support”选项,并勾选,然后会提示重启android studio ,点击重启,ok,如果已经设置好SDK的路径的话,问题解…

随机JCache内容:多个提供程序和JMX Bean

JCache(JSR 107)是用于缓存的Java标准…足够了。 没有更多介绍性的东西。 这是一则速成文章,内容涉及 多个JCache提供程序配置,以及 功能:通过JMX Mbeans的JCache统计信息 管理多个JCache提供程序 如果您只使用一个…

HDU 2222 ac自动机模板

题意: 求n个模板串在匹配串中出现了几个. SOL: 反正就是模板啦...似乎比KMP都简单----这么说似乎有点不道德...毕竟先看的KMP而他们并没有什么不同... 貌似自己的理解和他们画的图还是有些出入......不虚慢慢看... 然后就是特殊一点的一个last数组,可以比较迅速地找到包含的子串…

linux下spi添加设备,Linux Kernl添加spidev的设备节点

一、spidev介绍如果在内核中配置spidev,会在/dev目录下产生设备节点,通过此节点可以操作挂载在该SPI总线上的设备。用户空间通过该节点可以访问内核空间。二、配置spidev设备步骤在i.MX6,Kernel 4.1.15上配置spidev的支持。1、配置dts支持spi…

Android studio Jin开发生成so文件的具体步骤

粉丝提问: 博主解答: 帖子链接:https://blog.csdn.net/wangsfine/article/details/51445199

linux中改变文件大小,Linux 改变文件大小的方法

函数原型:#include int ftruncate(int fd, off_t length); //改变文件大小为length指定大小;返回值 执行成功则返回0,失败返回-1。函数ftruncate会将参数fd指定的文件大小改为参数length指定的大小。参数fd为已打开的文件描述词,而且必须是以…

Ubuntu下使用SVN

Ubuntu下使用SVN SVN作为日常开发中不可缺少的工具,今天终于开始在Ubuntu下使用了。 1、首先需要安装SVN。Ubuntu下的SVN安装十分简单,sudo apt-get install subversion,然后根据提示一步一步,就完成了SVN的安装; 2、检…

apktool重新打包,error:No resource identifier found for attribute ‘compileSdkVersionCodename‘ in package

报错日志:AndroidManifes.xml :1 error:No resource identifier found for attribute compileSdkVersionCodename in package ‘android’ 粉丝提问: 报错图: 博主解答:

linux弹性网卡,将弹性网卡附加到 ECS 实例上之后如何配置弹性网卡

本文在介绍将弹性网卡附加到 ECS 实例上之后如何配置弹性网卡的基础上,重点探讨了其具体步骤,本文内容很紧凑,希望大家耐心学习。配置 ECS 实例的弹性网卡如果您的实例使用以下几种镜像,您不需要手工配置弹性网卡(ENI)&#xff1a…

vaadin_嵌入式码头,Vaadin和焊接

vaadin当我开发Web应用程序时,我希望能够从Eclipse快速启动它们,而不必依赖各种重量级的tomcat或glassfish插件。 因此,我经常要做的就是创建一个可以直接从Eclipse直接运行的基于Java的简单Jetty启动器。 该启动器会在几秒钟内启动&#xff…

终端-进入云服务器

解决办法: 1.先进入管理员模式: 2.下一步,链接服务器。 3.已经连接上服务器: 4.找到云服务器的项目路径: 在这里: 我们可以在cd空格/ 按Tab寻找下个文件夹,也可以输入ls查看文件夹。转载于…

Android studio 清除缓存数据的步骤

导读:在eclipse的当中进行运行Android的运用的程序的时候,就会产生内存缓存的信息,而eclipse是可以直接点击停止运行程序,然后点击清除缓存,就可以解决了这个问题,而Android studio却不能直接点击停止运行的,而只能通过其它的方式来清除Android studio中的缓存。 可以看…

linux 函数 文件校验,Linux中的文件效验命令

在网络传输、设备之间转存、复制大文件等时,可能会出现传输前后数据不一致的情况。这种情况在网络这种相对更不稳定的环境中,容易出现。那么校验文件的完整性,也是势在必行的。md5sum命令用于生成和校验文件的md5值,MD5全称报文摘…

为Java应用程序编写数据驱动的测试

JUnit是一个功能非常强大的测试框架,它不仅为其用户提供了编写快速简便的测试的功能,而且还为用户提供了扩展它并使其按其期望的方式工作的机会。 在JUnit之上构建了许多框架,这些框架为目标受众提供了各种易用的功能。 EasyTest是这样一种框…

为《31天成为IT服务达人》征求正式名字

写书时。没细想书的名字,仅仅是在想出本能够让同行或未来同行高速入门的书,如今想来还是应正式给他取个名,请朋友们帮忙哟 转载于:https://www.cnblogs.com/bhlsheji/p/5241848.html

设置按钮5秒后可以点击下一步||5秒后自动关闭网页

场景:业务需要在点击拍摄的时候提示一个用户须知页面,5秒后可以点击下一步。这属于一个js计时器的功能。这里用jQuery实现一下 效果图: html <div style="text-align: center;"><input type="button" value="下一步" id="next…