最近没事喜欢看看,一些js库的源码,结果发现库前不是加一个!就是加+或者一个(),心中猜出个大概知道这个是让函数自动执行,可是这么多符号达到同一个目的,原理是什么呢,下面做一下剖析:

先从IIFE开始介绍

IIFE(Imdiately Invoked Function Expression 立即执行的函数表达式)

function(){
alert('IIFE');
}

把这个代码放在console中执行会报错

因为这个是一个匿名函数,要想让它正常运行就必须给个函数名,然后通过函数名调用。

好了这下知道为啥我们看到很多类库写的时候也是匿名函数结果不报错了吧,就是因为这些前面加的符号的原因。

其实在匿名函数前面加上这些符号后,就把一个函数声明语句变成了一个函数表达式,是表达式就会在script标签中自动执行。

运算符

①为什么加上了这些运算符后就能让一个匿名函数变成一个不会报错的函数表达式呢?

我们自然会想到javascript的解析器到底是怎么工作识别的呢,js解析器执行js表达式这个肯定是没有问题的。其实无论是括号,还是感叹号,让整个语句合法做的事情只有一件,就是让一个函数声明语句变成了一个表达式。所以我们让一个函数定义变成一个函数表达式来执行就不会报错。

②原理

这样是一个函数声明
function a(){
alert('IIFE');
}
这样是一个函数调用
a();
理解一下就是在一个声明了的函数后面加上一个()就可以调用函数了
function a(){
alert('IIFE');
}()
就这样

但是我们按上面在console中执行发现出错了

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

但是括号则不同,它将一个函数声明转化成了一个表达式,解析器不再以函数声明的方式处理函数a,而是作为一个函数表达式处理,也因此只有在程序执行到函数a时它才能被访问。所以,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。所以,赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的

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

性能

针对这些一元运算符,到底用哪个好呢,测试发现()的性能最优越,但是差别都不是特明显,所以对于一个库来说用几个这样的符号来说看不出什么影响,所以平常用! + -都可以,就看个人的代码习惯,当然最好还是用()。

参考:

①http://swordair.com/function-and-exclamation-mark/

② http://suqing.iteye.com/blog/1981591

从function前面的!想到的的更多相关文章

  1. JavaScript中Function函数与Object对象的关系

    函数对象和其他内部对象的关系 除了函数对象,还有很多内部对象,比如:Object.Array.Date.RegExp.Math.Error.这些名称实际上表示一个 类型,可以通过new操作符返回一个对 ...

  2. js中使用this的一些注意事项

    先看看这段代码 var x =9; var fobj ={ x:1, test:function(callback){ var x= 2; callback(); } } function pp(){ ...

  3. js函数对象

    函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解. javascript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质,可以很 ...

  4. Javascript中的函数(三)

    一:概述 函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解.JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质 ...

  5. Kotlin 型变 + 星号投影(扯蛋)

    Kotlin中的型变: 1. in,顾名思义,就是只能作为传入参数的参数类型 2.out, ..............,就是只能作为返回类型参数的参数类型 星号投影: 我们引用官网的吧-- For ...

  6. javascript 函数对象

    http://hi.baidu.com/gdancer/blog/item/a59e2c12479b4e54f919b814.html jQuery的一些写法就是基于这篇文章的原理的..     函数 ...

  7. javascript精雕细琢(四):认亲大戏——通过console.log彻底搞清this

    目录 引言 代码在前 1.function下的this 2.箭头函数下的this 结语 引言        JS中的this指向一直是个老生常谈,但是新手又容易晕的地方.我在网上浏览了很多帖子,但是发 ...

  8. 深入理解JavaScript函数

    本篇文章主要介绍了"深入理解JavaScript函数",主要涉及到JavaScript函数方面的内容,对于深入理解JavaScript函数感兴趣的同学可以参考一下. JavaScr ...

  9. Mybatis插入实体类字段为关键字解决方案

    1. Mybatis插入实体类字段为关键字解决方案 1.1. 前言 可能你插入字段为关键字时报如下错误,且字段名不适合改变 You have an error in your SQL syntax; ...

随机推荐

  1. atitit.404错误的排查流程总结vOa6

    atitit.404错误的排查流程总结vOa6 1. 场景 1 1.1. 子应用猛个腊擦不能使用  404 兰.. 1 2. 服务器配置问题 2 2.1. 登录服务器管理子应用,查看应用是否启动okk ...

  2. atitit.提升备份文件复制速度(1) -----分析统计问题and解决方案

    atitit.) -----分析统计问题and解决方案 1. 现在的情形 1 2. 硬盘信息 大概50mb/s, 50iops 1 3. 统计小的文件比率 2 4. 复制速度估计.. 2 5. 小文件 ...

  3. atitit.解决net.sf.json.JSONException There is a cycle in the hierarchy

    atitit.解决net.sf.json.JSONException There is a cycle in the hierarchy 1. 环境:使用hibernate4跟个,,要不个哪的对象系列 ...

  4. ES6类与模块

    class Animal { // 构造方法,实例化的时候会被调用,如果不指定,那么会有一个不带参数的默认构造函数 constructor(name, color) { this.name = nam ...

  5. python爬虫代码

    原创python爬虫代码 主要用到urllib2.BeautifulSoup模块 #encoding=utf-8 import re import requests import urllib2 im ...

  6. 取消 virtualStore 注册表[启用和禁止 UAC虚拟化]

    近日发现,在win2008R2 x64下运行的服务器程序,其注册表读取路径为: [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SZDomain\itvc1] 但是经 ...

  7. Speech两种使用方法

    COM组件使用speech: public class Speach { private static Speach _Instance = null ; private SpeechLib.SpVo ...

  8. JAVA B/S系统实现客户端屏幕截图,Java版的QQ截图

    简介:本方法首先需要抓到屏幕的整个图象,将图象显示在一个JFrame中,再将JFrame全屏显示,这样就模拟出了一个桌面,Java也就可以获得鼠标的作用区域从而实现桌面中的小范围截屏.Java实现QQ ...

  9. Java蛇形数组的简单实现代码

    上周五和朋友聊天谈到个蛇形数组的java实现办法,命题是:假设一个二维数组宽w高h,从1开始蛇形输出. int[][] numberMatric = new int[w][h]; 当时午睡过头脑袋不清 ...

  10. 深入分析Java Web技术(2) IO

    IO是当今Web面临的主要问题之一,可以说,大部分web应用的瓶颈都是IO的瓶颈. Java的IO类是java.io.它包含有80多个类,分为4大部分: 基于字节操作: InputStream,Out ...