V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wzl20001001
V2EX  ›  Vue.js

各位前端大佬,请教一个莫名其妙的前端 JS 问题。

  •  1
     
  •   wzl20001001 · 2020-10-29 20:29:34 +08:00 · 2520 次点击
    这是一个创建于 1487 天前的主题,其中的信息可能已经有所发展或是发生改变。

    撸代码时出现了一个奇怪的 Bug 。

    主要逻辑是用 axios 获取后端接口返回的状态码,如果成功则将表单值置为空,以便下次添加。

    但是当在控制台输出的时候,输出的对象是先经过主函数的 then 中的语句更改过的对象,但是如果读取其中的属性值,却是未经过更改的值。

    测试的执行顺序也是输出的 1,2,3 的顺序(先是执行 dispatch 之前的语句,接着执行 action,最后执行 then 中的语句)。

    有一点实在想不通:为啥还没运行到赋值语句,直接输出对象会是赋值后的样子。而且只有输出对象时,控制台显示对象的属性值是更改,但直接对象中的属性值时却未改变。

    这是主函数:

    addBookmark() {
    
      console.log(1)  // 1, 测试,用于测试执行顺序
      console.log(this.newBookmarkInfo) // 获取到的对象是经过过 then 中修改之后的对象 {bookmarkId:0, bookmarkTitle:1, bookmarkUrl:1}
      console.log(this.newBookmarkInfo.bookmarkTitle) // 获取到的是未经更改的 title: "title"
    
      this.$store.dispatch('addBookmark',this.newBookmarkInfo).then(() => { // 调用 Action
    
        console.log(this.newBookmarkInfo) // 同样是值更改过的对象
        console.log(this.newBookmarkInfo.bookmarkTitle) // 获取到的是未经更改的对象中的 title: "title"
    
        // 赋值语句
        this.newBookmarkInfo.bookmarkTitle='1'
        this.newBookmarkInfo.bookmarkUrl='1'
    
        console.log(3)  // 3
    
        // 对表单状态和弹窗状态的重置
        this.$refs.obs.reset()
        this.dialog = false
      }).catch(error => {
        console.log('error')
        console.log(error.response)
      })
    },
    

    这是 vuex 中的 Action:

    addBookmark(undefine, newBookmarkInfo){
      console.log(2)  // 2 
      console.log(newBookmarkInfo)  // 同样也是被更改过的对象
      console.log(newBookmarkInfo.bookmarkTitile) // 获取到的是未经过更改的 title
      return new Promise((resolve,reject) => {
        addBookmarkOne(newBookmarkInfo).then(resp => {
          const { data } = resp
          resolve(data)
        }).catch(error => {
          reject(error)
        })
      })
    },
    

    这是运行的控制台截图:

    屏幕截图 2020-10-29 201832.png

    第 1 条附言  ·  2020-10-31 02:23:10 +08:00
    晚上搞其他的组件的时候发现问题了,在值传递的时候没有进行对象拷贝,直接把源对象赋值给了变量,导致了加入 vuex 的一直是对源对象的引用。
    第 2 条附言  ·  2020-10-31 02:24:10 +08:00
    谢谢各位大佬的指引,最后终于发现问题了,差点自闭掉。
    第 3 条附言  ·  2020-10-31 02:34:08 +08:00
    关于 Chrome 和 Firefox 的值显示的延迟获取的问题,和各位大佬所说的一致。
    8 条回复    2020-10-31 02:21:30 +08:00
    shintendo
        1
    shintendo  
       2020-10-29 21:01:37 +08:00   ❤️ 3
    简单地说,chrome 在 console.log 输出对象的时候,输出的是对象的引用,而非对象内容的“快照”,你点+号展开的时候才对内容求值
    shintendo
        2
    shintendo  
       2020-10-29 21:03:01 +08:00   ❤️ 3
    补充,解决这个问题的一个方法是 console.log(JSON.parse(JSON.stringify(obj)))
    wzl20001001
        3
    wzl20001001  
    OP
       2020-10-29 21:05:50 +08:00
    @shintendo 懂了,谢谢大佬。一直以为是代码的问题,没往这方面想。
    SxqSachin
        4
    SxqSachin  
       2020-10-30 08:38:13 +08:00
    你可以尝试在每一句 console.log 下加一行 debugger;,来看那个时点这个对象的值。
    azcvcza
        5
    azcvcza  
       2020-10-30 09:45:57 +08:00
    火狐还是什么浏览器就严谨一点,到了对象该输出的时候才输出。chrome 的话,如果一开始一个{},打印的时候没值,但异步之后有值,那么之前打印的那条也会变成有值
    fengmumu
        6
    fengmumu  
       2020-10-30 10:37:35 +08:00
    @azcvcza 火狐
    azcvcza
        7
    azcvcza  
       2020-10-30 11:02:38 +08:00
    @fengmumu 可以
    wzl20001001
        8
    wzl20001001  
    OP
       2020-10-31 02:21:30 +08:00 via Android
    @SxqSachin 今天晚上搞其他的组件的时候发现问题了,在值传递的时候没有进行对象拷贝,直接把源对象赋值给了变量,导致了加入 vuex 的一直是对源对象的引用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   900 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:47 · PVG 04:47 · LAX 12:47 · JFK 15:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.