(...args) => fn(...args) 有没有垃圾回收的问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
az22c
V2EX    React

(...args) => fn(...args) 有没有垃圾回收的问题?

  •  1
     
  •   az22c 2020 年 9 月 11 日 2795 次点击
    这是一个创建于 2027 天前的主题,其中的信息可能已经有所发展或是发生改变。
    js 函数柯里化或者实现语法糖经常用到这种逻辑:

    const adder = (...args) => dispatch(...args)。 // dispatch 可以任意普通函数。

    我看到 redux 源码里面也是这么用,甚至很多开源 react 项目是这么写。最近和面试官讨论,对方说这样会产生闭包,甚至有内存泄漏的风险。

    我回头 chrome 再测试调试一下,好像没有看到有闭包。不知道是不是我的理解有问题
    10 条回复    2020-09-12 13:27:58 +08:00
    KuroNekoFan
        1
    KuroNekoFan  
       2020 年 9 月 11 日
    你面试官记混了吧,是 arguments object 有可能导致内存泄漏,而且跟闭包没关系
    https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Functions/arguments
    ethusdt
        2
    ethusdt  
       2020 年 9 月 11 日
    「有内存泄漏的风险」这句话怎么说都是正确的, 谁也不能保证浏览器是否释放应该被释放的变量. 但 「 (...args) => dispatch(...args)」这么写并没有内部变量呀, 有啥好泄漏的 ?

    不过还是要讲个例子(浏览器的 bug): https://bugs.chromium.org/p/chromium/issues/detail?id=315190

    var someClass = function() {
    console.log('some');
    };

    function getter() {
    var some = new someClass();
    if(true) {
    return function() { //I'm done with some and don't need it
    return null;
    };
    } else {
    return function() {
    return some;
    };
    }
    }

    window.f = getter();

    这个代码执行完理论上变量 some 会被回收, 因为 closure 没有 catch 住 some, 但通过 devtools 里 memory - [heap snapshot] 可以发现 变量 some 没有被 GC.

    所以, 这就是定义一个变量都有「有内存泄漏的风险」.
    az22c
        3
    az22c  
    OP
       2020 年 9 月 11 日
    @FaiChou 你这个例子是特殊情况,编译的时候没法分析出 if true 。感觉是两回事,话题扯得比较远了。
    @KuroNekoFan 是 ,问题讨论集中到对 args 的引用上,有没有闭包。搞个测试代码测试一下,还是挺明显的
    soulmt
        4
    soulmt  
       2020 年 9 月 11 日
    what 这会产生闭包? 应该说有可能会产生吧,es6 这种用法不是很多么,赶紧跑吧,这还面啥
    az22c
        5
    az22c  
    OP
       2020 年 9 月 11 日
    @soulmt
    @KuroNekoFan
    好像明白了
    像 react-redux,这个“dispatch 函数”是作为函数参数传入本函数中,没有闭包问题。

    function mapDispatchToProps(dispatch) {
    return {
    adder: (...args) => dispatch('function name', ...args),
    }
    }

    connect(mapStateToProps, mapDispatchToProps)(Component)


    -------------------------

    而如果这个 dispatch 函数作为当前函数的内声明的函数,并且该函数返回 adder,是有闭包。
    KuroNekoFan
        6
    KuroNekoFan  
       2020 年 9 月 11 日   1
    @az22c 按照闭包的定义,在一个 function 里在定义一个 function 就形成了一个闭包,但是闭包跟内存泄漏没有必然联系...
    finalwave
        7
    finalwave  
       2020 年 9 月 11 日
    @FaiChou #2 这不是 V8 同一作用域函数共用内存和块状作用域内函数变量提升搞出来的问题嘛,换个引擎就好了(狗头
    ethusdt
        8
    ethusdt  
       2020 年 9 月 12 日
    @finalwave #7 GC 是引擎自己实现的, 代码都是有 bug 的, 所以它有泄漏的风险 ( 逃
    usw
        9
    usw  
       2020 年 9 月 12 日
    咋着,还指望把 dispatch 给你回收掉
    wxsm
        10
    wxsm  
       2020 年 9 月 12 日 via iPhone
    遇到这种情况建议追问:具体是那一部分的内存泄漏?怎么个泄露法?怎么写才能不泄露?如果对方不懂,那就暴露了。如果真懂,那就学到了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6145 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 06:13 PVG 14:13 LAX 23:13 JFK 02:13
    Do have faith in what you're doing.
    ubao msn 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