zoukankan      html  css  js  c++  java
  • js对象等号赋值的bug

    var a = {n: 1};
    var b = a;
    a.x = a = {n: 2};
    
    console.log(a.x);
    console.log(b.x);
    有道题是这样的,觉得很奇葩,分析一下

    1.对象 引用类型

    对象属于引用类型,c,java,js里面都是的,对象就是引用类型,包括数组。

    上面的a是引用类型,a保存的是对象 {n: 1}的地址,对这个对象的引用。b = a 。把a里面的地址赋值给了b,b也指向{n: 1}这个对象的物理地址。所以,a 一旦做赋值更改,修改的是a对引用的修改。b也同时修改,b修改的时候,a也会被修改。这就是引用类型。

    堆和栈。堆是真实的{n:1} 。栈里面存放的是堆的物理地址,值比较小。根据栈的地址去找堆里面的数据。

    2.

    var a = {n:1};
    var b = a;
    a.x = a = {n:2};
    console.log(a===b.x); //true
    

      第二个奇葩结果

    3.

    https://blog.csdn.net/qiphon3650/article/details/78860973

    我把这篇看了,然后觉得还是不理解

     就这句: 执行a.x=a,此时a已经指向了新对象,而a.x因为在执行前保留了原引用。

    不理解的点是 a都已经改变指向了,a指向了{n: 2},a.x里面的a的指向当然也改变成了{n: 2},为什么,a.x还会保留原引用

    4.我又看了别人写的,觉得这样比较好绕回来

    a.x的运算优先级最高

    也就是说

    var a = {n:1};
    var b = a;
    a.x = a = {n:2};
    console.log(a===b.x); //true

    这段代码可以写成这样

    var a = {n:1};
    var b = a;
    a.x = (a = {n:2});
    console.log(a===b.x); //true
    

      

    这样就解释通了

           1.a指向 {n: 1};   ---> var a = {n: 1};

           2.b指向 a指向的这个 {n: 1}  ---> var b = a;

      3.计算 a.x = (a = {n: 2});    a.x的值是 后面值的结果,后面的值先不管。此时 a.x = (某个值),是先计算的。a.x 这个a 指向并没有被         改变

      所以. a.x 里面的a仍然是原来的 {n: 1};a.x里面的值是后面( a = {n: 2})这个结果的返回值。这个返回值是 {n: 2};

           4.所以拆分成a.x = { n: 2 }; 然后原来的a的值被 a = {n: 2},b是对原来对象的引用; a 最后赋值的结果是a = {n: 2};

            所以。a.x是underfined,因为新的a里面并没有 x这个属性

    所以我觉得这个赋值运算的结果,a = {n: 2}这个a并没有更改引用的时候,它的返回值就已经确定了,就先赋值给原来的a.x里面的a了。我只是猜想。。。连等式可能并不会去计算过程,其中所有的值都直接被最后一个等号的值给赋值,其中,引用类型的赋值. 会优先赋值计算。

    这个图表示最后的结果,并不能表示赋值过程。

  • 相关阅读:
    搭建ip代理池思想
    maven中央仓库
    git 基本操作
    利用阿里云发送信息
    Ubuntu配置java环境
    mysql 配置
    Quartz中的时间配置
    如何在Maven中配置Spring依赖
    Jquery动态添加/删除表格行和列
    改行做窗纱批发了(浙江绍兴柯桥窗纱)
  • 原文地址:https://www.cnblogs.com/chenyi4/p/11381371.html
Copyright © 2011-2022 走看看