一道面试题之点操作符优先级

80 阅读2分钟

直接上代码

    var a = { n:1 }; 
    var b = a; 

    a.x = a = { n:2 };


    alert(a.x); // undefined
    alert(b.x); // { n: 2 } 

为什么第一个是 undefined 呢 ? 我们来分析一下 !

  1. 首先 a 指向一个堆地址, 内容为 n: 1
  2. 然后 b 指向 a, 其实也就是 b 和 a 目前指向了同一个堆地址
  3. a.x 点操作符的优先级为 19, 而等号操作符的优先级为 10, 所以点操作符指向是在赋值前, 也就是我们先给 a 指向的堆地址, 重新分配了一个 key 值 x 的变量, 此时并没有赋值操作, 相当于给此时指针指向的堆地址分配了一个key为x的变量,但是没给值。并且点操作符计算锁定!就是说就算此时给a重新赋值,指向另一个堆地址,a.x 也是指向 { n: 1, x: undefined } 堆内存中的 x
  4. 点操作符执行完成后, 开始执行等号操作符, 按照约定从右向左执行, 也就是依次执行
        a = { n: 2 } // 此时 a 为 { n: 2 }
        [a.x] = a // 此赋值执行前 [a] = { n: 1, x: undefined } [a.x] = undefined  
    
    中括号代表不会重新计算 a.x 的指向的内存地址, 也就是说 此时的a 虽然指向了新的内存区 { n: 2 }, 但此处(点操作符)已被执行过了, 计算的时候 a 还是 和 b 指向一个内存区域,然后执行赋值语句 [a.x] 也就是 b.x 指向 a。 此刻 a = { n:2 } 所以 b = { n: 1, x: { n: 2 } }
  5. 完成全部赋值操作 此时 b 指向的堆地址的值为 { n: 1, x: { n: 2 } }, a 指向的堆地址为 { n: 2 }

建议画图理解