V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
frontman
V2EX  ›  程序员

javascript 中!function(){} 方法前面一个分号是啥意思

  •  
  •   frontman · 2014-09-04 16:23:45 +08:00 · 15435 次点击
    这是一个创建于 3740 天前的主题,其中的信息可能已经有所发展或是发生改变。
    经常在框架中看到 !function(){} 这样的表达式 不明觉厉 不知其意
    第 1 条附言  ·  2014-09-05 14:40:02 +08:00
    标题是感叹号 当时打错了 不过大家回答的都是叹号 已经明了 非常感谢 姿势瞬涨
    34 条回复    2014-09-05 14:38:57 +08:00
    Zhang
        1
    Zhang  
       2014-09-04 16:26:49 +08:00
    javascript里函数就是一个object,函数前面加!就表示“空object”吧。
    subpo
        2
    subpo  
       2014-09-04 16:29:09 +08:00   ❤️ 1
    +function !function === (function(){})()
    subpo
        3
    subpo  
       2014-09-04 16:30:31 +08:00   ❤️ 1
    原理是加一个运算符会实时触发这个函数,不过我记得~function已经加到ES6了?依稀有这么印象
    ZhaoMiing
        4
    ZhaoMiing  
       2014-09-04 16:32:19 +08:00   ❤️ 1
    54c3
        5
    54c3  
       2014-09-04 16:33:23 +08:00   ❤️ 2
    這又是 javascript 的 trick,假如有個匿名函數`function(){ console.log('yooo'); }`,要調用它一般用`(function(){ console.log('yooo'); })()`,js 解釋器碰到一開始的左括號就會把後面解釋為一個表達式。而`function(){ console.log('yooo'); }()`卻會語法錯誤,因為 js 解釋器看到 function 自動默認為函數定義了。這時可以用`!function(){ console.log('yooo'); }()`,前面的「!」會指引解釋器告訴它後面是一個表達式,所以效果和用括號括住匿名函數定義一樣,但是省一個字符。
    Zhang
        6
    Zhang  
       2014-09-04 16:35:06 +08:00   ❤️ 1
    我能删除我的回复么?
    NemoAlex
        7
    NemoAlex  
       2014-09-04 16:35:49 +08:00   ❤️ 1
    标题说的分号原来是叹号啊
    ZhaoMiing
        8
    ZhaoMiing  
       2014-09-04 16:36:56 +08:00   ❤️ 1
    分号是为了避免跟其他文件压缩合并是出现错误。
    feiyuanqiu
        9
    feiyuanqiu  
       2014-09-04 16:41:26 +08:00
    @Zhang haha
    所以回复的时候要认真思考一下呢...
    Zhang
        10
    Zhang  
       2014-09-04 16:51:59 +08:00
    @feiyuanqiu 刚学javascript,因为觉得这货很有用,虽然很tricky,也不优雅,也不严谨。
    tsingchao
        11
    tsingchao  
       2014-09-04 17:35:36 +08:00
    function(){} 函数声明 函数名称为必须
    !function(){} = (function(){}) 函数表达式 函数名称可选
    tushiner
        12
    tushiner  
       2014-09-04 18:01:06 +08:00
    一楼最亮,哈哈
    tushiner
        13
    tushiner  
       2014-09-04 18:03:57 +08:00
    又长姿势了。给出正解的都是大神。
    AsterOcclu
        14
    AsterOcclu  
       2014-09-04 18:41:47 +08:00
    推荐看看http://swordair.com/function-and-exclamation-mark/ 这篇文章,下面还有明确的性能评测~
    shoumu
        15
    shoumu  
       2014-09-04 18:59:18 +08:00
    今天也想到了这个问题。。
    zythum
        16
    zythum  
       2014-09-04 19:08:52 +08:00
    @subpo
    应该说所有符号~function 的效率是最快的...
    54c3
        17
    54c3  
       2014-09-04 19:41:34 +08:00 via Android
    @zythum 唔…為什麼我覺得好喪病…
    digimoon
        18
    digimoon  
       2014-09-04 19:59:24 +08:00
    @54c3 能解释一下(function(){})()这种是什么意思么新手不懂,或者找资料的话这种名字是叫什么?
    xiandao7997
        19
    xiandao7997  
       2014-09-04 20:13:17 +08:00 via Android
    @digimoon 前面一个圆括号里创建了一个匿名函数,最后面一个圆括号表示立即执行它
    应该是叫即时匿名函数吧,可以翻翻《JavaScript 高级程序设计》
    jarontai
        20
    jarontai  
       2014-09-04 20:14:36 +08:00
    @digimoon 这是js里有名的IIFE(立即执行函数表达式),常用来创建一个匿名的命名空间,避免污染顶(上)层空间
    bombless
        21
    bombless  
       2014-09-04 20:50:03 +08:00
    分号和叹号是两种不同的情况……
    分号的作用是在每行都不手打结尾的分号的情况下避开自动插入分号导致的解析错误
    叹号类似加号、减号、new操作符什么的,可以少写一个括号(用new操作符的话函数调用的那对括号都省了)

    这些手法都是依赖于js语法解析的细节。
    Tonni
        22
    Tonni  
       2014-09-04 21:51:10 +08:00 via Android
    立即调用函数声明
    codepiano
        23
    codepiano  
       2014-09-04 21:57:49 +08:00
    加个!号会被当成表达式解析,因此也就调用了该函数,和(function(){})()一样
    Biwood
        24
    Biwood  
       2014-09-04 22:01:20 +08:00
    听到过一种解释:
    分号是为了防止这段代码的前一段javascript代码结尾没有分号,避免运行时发生错误
    leeiio
        25
    leeiio  
       2014-09-04 23:07:58 +08:00
    这不是叹号么...
    yyfearth
        26
    yyfearth  
       2014-09-05 01:53:53 +08:00
    @leeiio 他的意思应该是 `;!function(){...}`

    目的是防止在minify合并行的时候由于前一行缺少分号导致错误 比如:
    alert(1)
    !function(){...}

    合并后变成 alert(1)!function... 就syntax error了 加一个分号就好了 反正多一个没关系 少一个就不行
    yyfearth
        27
    yyfearth  
       2014-09-05 01:57:51 +08:00
    @tsingchao 应该是 (function(){}()) 或者 (function(){})() 两者等价

    @digimoon 其实很简单 相当于你定义一个函数然后立即执行它:
    var x = function() {....}; (或者 function x() {...}) 然后马上 x();
    目的主要是为了避免污染全局变量 或者 为了使用闭包
    acros
        28
    acros  
       2014-09-05 02:01:16 +08:00 via iPad
    我想知道你们管右边这符号叫什么-> ;
    luguozmy
        29
    luguozmy  
       2014-09-05 08:40:49 +08:00
    人家明明问的是分号, 一帮人都在回答什么呀, 分号感叹号傻傻分不清楚
    tsingchao
        30
    tsingchao  
       2014-09-05 09:58:53 +08:00
    @yyfearth 加括号是立即执行 不谢
    leejaen
        31
    leejaen  
       2014-09-05 09:59:03 +08:00
    这种tricky code 还是少写为好,技术不能用来秀的,达到要求才是最好的嘛。自己一个人懂不能保证团队里面其他人都懂,有可能会导致项目问题的。还有一些javascript的tricky code,比如with表达式、if(a=b){……}最好都别用,其他像左边大括号最好跟在行尾、每句要分号的一定要加上等也要遵守。这里应该号召大家讨伐写那代码的人。所以,写成最笨的(function(){……})();我觉得挺好。
    54c3
        32
    54c3  
       2014-09-05 12:25:40 +08:00
    @digimoon 這種叫 Immediately-Invoked Function Expression (IIFE),見: http://weizhifeng.net/immediately-invoked-function-expression.html
    frontman
        33
    frontman  
    OP
       2014-09-05 14:31:27 +08:00
    @NemoAlex 哈哈 你的钻眼 小生立马就改
    frontman
        34
    frontman  
    OP
       2014-09-05 14:38:57 +08:00
    为何现在改不了标题了 是感叹号 当时打错了 不过大家都回答的是感叹号 非常感谢大家 已经明了了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1010 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:56 · PVG 03:56 · LAX 11:56 · JFK 14:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.