V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
mskf
V2EX  ›  JavaScript

请教一下,怎么理解这段 JavaScript 代码?

  •  
  •   mskf · 2019-12-05 04:11:40 +08:00 · 3327 次点击
    这是一个创建于 1576 天前的主题,其中的信息可能已经有所发展或是发生改变。
    const main = ()=>{
        const a = ()=>{
            console.log("A")
        }
    
        const b = {
            a,
            s:1
        }
        fb(b)
        console.log(b.a)
    }
    
    const fb = (o)=>{
        const back = o.a
        o.a=null
        o=JSON.parse(JSON.stringify(o))
        o.a=back
        return o
    }
    
    main()
    
    
    

    解释一下,fb 的作用是把对象中不能序列化的那部分暂存,序列化并复制到新对象后放回去

    我知道这种深复制很耗性能,但问题在于,输出的永远是 null

    更奇怪的是,在 fb 的返回处设置断点,可以看见 o.a 是我们的 function,但是返回上一个函数栈后,这个值突然就变空了

    解决的办法是,把深复制去掉,或者是改成 b = f(b)

    那么有没有比较官方的原因解释呢

    7 条回复    2019-12-05 10:52:35 +08:00
    jfcherng
        1
    jfcherng  
       2019-12-05 04:28:24 +08:00 via Android
    你覺得 fb = (o) { o = {}; } 能把外部的 b 清空嗎
    dartabe
        2
    dartabe  
       2019-12-05 04:37:12 +08:00
    const 声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。
    mskf
        3
    mskf  
    OP
       2019-12-05 04:37:36 +08:00
    @jfcherng 请你仔细看一下,解决问题的办法是把序列化和反序列化去掉,也就是说问题出在对象复制这里,值传递和引用传递这种问题我还是清楚的
    mskf
        4
    mskf  
    OP
       2019-12-05 04:39:58 +08:00
    @dartabe 没错,const 创建的对象可以改变自身的引用,但是请你仔细看一下,问题也不是出在变量声明上,无论使用的是 const 还是 var,结果都是一样的
    jfcherng
        5
    jfcherng  
       2019-12-05 04:45:55 +08:00
    當你決定做出 o = what_ever_expression; 的那刻, 這個 o 已經不是外部的 b 了
    mskf
        6
    mskf  
    OP
       2019-12-05 04:51:54 +08:00
    @jfcherng 不好意思是我理解的问题。。。这个帖子 over 了
    luoh
        7
    luoh  
       2019-12-05 10:52:35 +08:00
    b = fb(b)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   964 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:24 · PVG 04:24 · LAX 13:24 · JFK 16:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.