A-A+

js文件中函数前加分号和感叹号是什么意思?有什么用

2016年01月26日 JavaScript 暂无评论 阅读 349 次

js文件中函数前加分号和感叹号是什么意思?有什么用

分号是为了和前面的代码隔开,js可以用换行分隔代码,但是合并压缩多个js文件之后,换行符一般会被删掉,所以连在一起可能会出错,加上分号就保险了。

你看到的感叹号一般是在压缩过的js文件里面,因为在匿名函数调用的时候,通常我们都是用:  (function(){})()  的形式,但也可以使用另一种形式:!function(){}() 前面的!号可以换成-+~等等一元操作符,从而省下了1字节。

从语法上来开,Javascript中分号表示语句结束,在开头加上,可能是为了压缩的时候和别的方法分割一下,表示一个新的语句开始。所以,如果在一个单独的JS文件中,开头的分号是没有任何意义的,可以删掉。

叹号是逻辑运算符,是“非”的意思,常见这种写法 if(!true){};而将运算符加载函数定义的前面,则是将函数看做一个整体,然后再调用这个函数,并对返回的结构进行逻辑运算。

说白了,此处就是构建了一个立即执行函数,建议楼主知道意思就可以,自己写的时候,可以使用更清晰的格式:

(function(){})();

 

这里补充一点:在函数声明【 function (){} 】后面加【 () 】,意思是执行这个函数声明。有的叫法是“匿名自动执行函数”,更准确的表示应该为“立即执行函数”。

 

但立即执行函数,要作为表达式的一部分才行,不然js解释器会报语法错误。一般,成为表达式的最容易理解方式是:在左右两端加一个圆括号,像这样【 (function (){}) 】。所以,立即执行函数最常见的写法是【 (function (){})() 】,这是一个语句,在前面和后面都可以加【 ; 】。

 

其实立即执行函数还有N种写法,比如【 (function (){}) 】也行,在函数声明前加一元运算符也行:【 !function (){}() 】、【 ~function (){}() 】。甚至,对一元运算符进行组合也可以:【 !!!!function (){}() 】、【 ~~~function (){}() 】、【 !~!function (){}() 】。

 

跟分号的宗教战争无关,这里主要是由于JS拥有ASI(自动分号插入)机制而隐藏的问题。比方说,正确说出下面代码的执行结果?(我已经给提示了~)

var test=function(a){
    alert(a)
    return function(c){
        alert(c)
    }
}(function(b){
    console.log(b)
})(1)

写IIFE的时候,在执行体前不主动加分号,上述代码就是一个坑.....(单个代码文件可以测试通过,但多个JS文件合并之后运行异常)

var test=function(a){
    alert(a)
    return function(c){
        alert(c)
    }
};(function(b){
    console.log(b)
})(1)

因为这两段代码生成的语法树是完全不一样的。详情请看Esprima: Parser,AST太长了,这里就不贴了。

 

是的。这里的变量也包括函数。函数也是一种变量。匿名写法可以避免变量全局污染。

比如。在别人写过的一段js代码中你想在里面加一些自己的代码。最好的做法就是用匿名函数包裹。举个例子来看为什么。

比如,已经存在一段别人写的代码了,假设这段代码很长你不想看。

//别人的代码
....
....很多
//这里他定义了一个叫foo的函数
function foo{
 ... 一些函数逻辑
}

好,现在你自己想在同一个页面里面加一些自己的代码。假如你不知道别人已经定义了foo函数,你又额外在自己的函数里面定义一次

function foo{
 ..
}

把这段代码加在了页面的最后。这样你的函数定义就覆盖了 原来别人i写的函数定义。

恰巧,在某个事件里面,就使用foo函数。这个时候,原来的逻辑就不能正确执行了。

假如你的定义写在匿名函数里面, 那么这个定义就对外部不可见的,不会覆盖原来的。这样就避免了变量污染。 实际的应用,你就去参考 流行js库的源代码。通常都是如下写法

;(function(){
 var ....
 ....
})()

这样就会避免变量污染了。

注意,在开始的第一个字符 使用 分号,这是因为避免出现代码压缩时产生意外的错误。因为js可以省写分号。假设有段代码是

....
return result

然后又在js合并压缩时 合并成一个文件

...
return reslut;(function(){...})()

如果没有分号就会成这样

....
return reslut(function(){...})()

在代码进行压缩后result 变成了一个函数了,这明显是错误的。

因此在匿名函数的前面加个 分号 也是个良好的习惯

标签:

给我留言

Copyright © web前端技术开发个人博客 保留所有权利  京ICP备14060653号 Theme  Ality

用户登录