js 文件里,匿名函数开头有个 ;! 意义是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
JiaFeiX
V2EX    问与答

js 文件里,匿名函数开头有个 ;! 意义是什么?

  •  
  •   JiaFeiX 2017-05-19 19:49:55 +08:00 via iPhone 4856 次点击
    这是一个创建于 3067 天前的主题,其中的信息可能已经有所发展或是发生改变。
    这是在贤心大神的 layim 代码里看到的,开头是 ;!function ( win,undefined ) {}结束还有个 ( window ) 啥意义呢? 是封装吗?

    截图:

    开头部分:
    ![]( http://i1.piimg.com/1949/18b3450b8154251e.jpg)


    结尾部分:

    ![]( http://i1.piimg.com/1949/2ce400a94a6fcc43.png)
    20 条回复    2017-05-21 01:45:42 +08:00
    JiaFeiX
        1
    JiaFeiX  
    OP
       2017-05-19 19:51:43 +08:00 via iPhone
    为了封装起来调用吗
    atan
        2
    atan  
       2017-05-19 19:59:23 +08:00   5
    分号是为了合并压缩的时候和其他函数做分割用的;感叹号是用于立即执行函数的,你可以换成加号减号的,和用括号包裹函数体作用一样
    newworld
        3
    newworld  
       2017-05-19 20:02:36 +08:00
    @atan #2 感谢 借楼长知识了 思密达
    JiaFeiX
        5
    JiaFeiX  
    OP
       2017-05-19 22:36:51 +08:00
    @atan

    ! function ( win,undefined ){ } ( window )

    最后括号里的 window 意义是什么? 看到 jquery 也是这样的, ( win,undefined ) 为什么是这两个参数呢?
    JiaFeiX
        6
    JiaFeiX  
    OP
       2017-05-19 22:41:23 +08:00
    JiaFeiX
        7
    JiaFeiX  
    OP
       2017-05-19 22:43:10 +08:00
    @atan

    ! function ( win,undefined ){ } ( window )

    这个函数,是不是吧 window 对象给装进去 作为函数的参数了?
    hahamy
        8
    hahamy  
       2017-05-19 22:51:52 +08:00
    @JiaFeiX 是的
    var a = function(win, undefined){};
    a(window);
    JiaFeiX
        9
    JiaFeiX  
    OP
       2017-05-19 23:26:59 +08:00
    @hahamy

    window 是指的一个 整个 window 对象都传进去了? 为什么这么做呢?
    U7Q5tLAex2FI0o0g
        10
    U7Q5tLAex2FI0o0g  
       2017-05-19 23:29:17 +08:00
    谷歌:闭包
    broven
        11
    broven  
       2017-05-19 23:49:55 +08:00 via iPhone
    明确依赖吧, 告诉你这个闭包里,明确的依赖了某一个对象,window 对象同理。
    yangff
        12
    yangff  
       2017-05-20 00:45:04 +08:00
    而且因为 undefined 可能不是 undefined ……
    比如
    (function (undefined) { console.log(undefined); }) (1)
    atan
        13
    atan  
       2017-05-20 01:51:16 +08:00
    window 参数的目的是将本来 window 这个全局对象变成自执行函数内部的局部对象;
    undefined 是确保自执行函数内部的 undefined 是真的未定义,万一被重写了赋了其他值
    geelaw
        14
    geelaw  
       2017-05-20 05:47:43 +08:00
    @atan
    @broven
    @yangff

    我认为这里 window 传入的作用是减少代码长度,因为参数名叫 win。

    另外我无法理解为什么有人要把 undefined 改成不是 undefined,这听起来就像是在 C++ 里面写

    #define false true

    一样
    yyfearth
        15
    yyfearth  
       2017-05-20 08:50:58 +08:00   1
    @JiaFeiX @atan @yangff
    这样做主要目的是为了更好的 minify 代码压缩 同时减少兼容性问题

    ; 为了保障文件在合并的时候没有换行的问题
    !function(){} +function(){} 作用和 (function(){}()) 一样立即执行函数 一般是 minify 后的代码有这样用

    (function(global, undefined){} (window 或者 this)) 这样做有 2 个好处
    一个是保证 global 和 undefined 不随便被改掉 以及不同平台兼容性问题
    同时 minify 过后 window 和 undefined 这样在参数里面变成了局部变量 可以被更短的名字替换
    比如变成 !function(g, u){} (window 或者 this) 这样就省了很多字节

    @geelaw undefined 那个好像是个历史遗留问题 这样做可以保证不被篡改
    同时这样写就和 win 一样 minify 后可以减少代码长度
    MrFireAwayH
        16
    MrFireAwayH  
       2017-05-20 10:18:46 +08:00 via Android   1
    @yyfearth 你的说法是对的

    +function (){}
    -function (){}
    !function (){}
    ~function (){}
    (function (){})()

    这种写法可以保证匿名函数立即运行且运行一次

    传入的 window 对象从全局变成了局部对象 优点有

    1. 运行更快了
    2. 可以随意改名 比如 a, 这样便于压缩
    3. 可以传入其他库而不导致冲突

    举例子
    (function ($, w, d, undefined){

    $(document).addClass('test');

    })(jQuery, window, document);

    这样的情况下 JQ 可以无痛使用 也不需要使用 noConflict 方法避免冲突

    至于传递 undefined 是因为 ES3 时代这个玩意儿是可以被修改的……真的有人会去做比如 undefined = true 这样的事情 所以说额外定义一个真正的 undefined 可以保证匿名函数内部的 undefined 是真正的 undefined(好累……)

    最后……

    @geelaw 又看到你了
    JiaFeiX
        17
    JiaFeiX  
    OP
       2017-05-20 12:55:39 +08:00
    @MrFireAwayH 手工感谢, 解释的很清楚。

    另外,有个疑问

    > 传入的 window 对象从全局变成了局部对象 优点有 运行更快了

    运行的更快了, 原理是什么?
    AnonymousID
        18
    AnonymousID  
       2017-05-20 14:44:54 +08:00   1
    @JiaFeiX 将 window 变为局部对象后,当在局部作用域内查找 window 时就直接能找到,如果不传入那么会顺着作用域链向上找,所以缩短了作用域链,缩短了查找过程,所以更快了,不知这样理解对不对
    HYSS
        19
    HYSS  
       2017-05-20 15:12:37 +08:00
    @atan 想问下你是从哪知道的
    MrFireAwayH
        20
    MrFireAwayH  
       2017-05-21 01:45:42 +08:00 via Android
    @AnonymousID 你说的很有道理

    就是作用域的问题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     864 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 20:32 PVG 04:32 LAX 13:32 JFK 16:32
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86