一句话告诉你为什么有些jQuery插件会有特殊字符(加号、减号、感叹号等)

来源:互联网 发布:淘宝客服主管考核 编辑:程序博客网 时间:2024/05/06 04:21

有时候看一些jQuery插件的代码前面总是会有一些特殊的字符放在最前面,比如!、~、+、搞不懂到底有什么用?不知各位有没有产生过这种疑惑。

那么现在我就用一句话概括一下这些看似无用的符号所起到的作用。

像!、+、-、||、&&等这些东西的存在是为了告诉解析器,要把下面的代码当作表达式执行,而不是函数!更直白的说就是告诉浏览器,下面这个没名字(匿名)的函数要当作匿名函数(或者说是立即执行函数)来解析。

一句话说完了,没看明白?那我就来按照这句话中的关键字简要的解释一下这句话的意思吧。

一、这句话的上下文

!、+、-、||、&&等符号的后面都是跟着一个function关键字的,他的结构就如下面的代码定义方式:

+function ($) {    //code}();

二、解析器‘优待’函数申明

浏览器在解析js代码的过程中涉及到一个扫描‘预编译’的过程(PS:不知道这么说合理否,毕竟js是解释型语言,和java这种编译语言处理过程是有差异的),这个过程中会有以下两个操作:①用var声明的变量设置为活动对象的属性,默认值为“undefined”,②以function定义的函数也添加为活动对象的属性,而且他们的值正是函数的定义;

与本文密切相关的第二步,function申明的函数将‘优先’处理。而用var 定义的函数表达式则被浏览器视为普通表达式,在解析器顺序执行js代码的时候才给这个定义的函数名设值。

这段话的代码解释:

函数申明方式:

var a = beloved();console.log(a);function beloved() {    return 'ok';};

函数表达式方式:

var b = notgood();console.log(b);var notgood = function () {    return 'bad';}

执行结果:‘



三、浏览器不喜欢没名字的‘孩子’

第二部分我们已经说明了js代码的执行顺序,但是我们发现,不管是在“预编译”的时候执行,还是在正式解析的时候执行,只要按照正常的函数结构来定义函数,都能被浏览器识别,但是可能是“计划生育”的原因,有些是js代码“超育超生”,没法给函数这个“函数小朋友”上户口(匿名函数),就像这样:

function () {    alert('i have noting,even a name.')}

执行结果:


但是又想让他在这个特殊的空间里“施展拳脚”,怎么办?“人怕出名猪怕壮”,我们偷偷的把他打扮一下,搞成个普通的不能在普通的“小朋友”,而不要像function那样被“优待”不就行了?!

(function () {    console.log('i have noting,but i  can run now.')}());
执行结果:


就是这样的包装,这个没有名字的“小朋友”,在今后的岁月中在闭包、模块编程方面做出了“杰出贡献”。

 

四、喜欢怎么写就怎么写

前三部分用了一些 不太恰当的例子讲了两个基础的知识,下面就切入正题,先看代码:

function () {    console.log('are you ok!!!')}();

执行结果:


(function () {    console.log('i am very ok!!!')}())!function () {    console.log('i am very ok!!!')}();~function () {    console.log('i am very ok!!!')}();+function () {    console.log('i am very ok!!!')}();true&&function () {    console.log('i am very ok!!!')}();
执行结果:

看了代码,估计大家都已经最开始那句话解释的意思了把,不明白那就在罗嗦一遍,这些符号的存在,就是告诉浏览器,“我是一个普通通的表达式,请你在正式执行的时候再解析我,而不是在预编的时候!”,符号就是在帮助匿名函数做“伪装”!好啦,要说的东西解释完毕!

其实匿名函数(立即执行函数)的写法是很随意的,你可以用任何自己习惯的写法来书写代码,也可以使用new关键字,像这样:

0, function () { /* code */ }();new  function() { /* code */ }() 

五、这个东西不一样

都介绍完了还有什么?这个不可缺少的东西就是分号(;)!!!

    这个东西为啥不一样?先看代码:

情况一:


情况二:

//    a.js    function purpose() {       console.log('i come from a.js')    };    purpose()//            忘记加分号了//b.js    (function sayok() {        console.log('b.js')    }());

执行结果:



//    a.js    function purpose() {       console.log('i come from a.js')    };    purpose()//            忘记加分号了//b.js    ;(function sayok() {        console.log('b.js')    }());

执行结果:


首先:我们可以发现,分号(;)是不可以放在立即执行函数前面的,它不具有转换function函数为表达式的功能,反而会告诉浏览器,“你看,就是家伙没户口”。再次:当我们在压缩合并同事间合作完成的代码时,就会出现第一种错误,由于别人漏泄了分号,自己的代码跑不转了,说不定你还要找好久出现的问题到底在哪。其实就是这个看着不起眼的分号。希望这个小tips能够帮助大家,在书写规范代码的问题上与君共勉。


因个人水品有限,总结的知识如果存在错误或者漏洞,请指出,感谢!





0 0