likes
comments
collection
share

带你迈过js赋值运算的坑(附带面试题)

作者站长头像
站长
· 阅读数 23

面试题

话不多说,我们先上面试题:

var a = { n: 1 } 
var b = a 
a.x = a = { n: 2 }

console.log(a.x);
console.log(b.x);

初见这道面试题,我相信所有的小伙伴们都可以看懂,但是解答(说出答案还要阐述过程)出来可能会有些费劲。我们先来看看答案:

undefined

{ n: 2 }

我们先来分析,这道题看上去是考察的 引用赋值 或者 循环引用 什么的,实际上不是。这道题就是考察的赋值运算符,所以我们先要搞清楚赋值运算符是怎么算的。

赋值运算符的计算

我们众所周知的是,赋值运算符 = 用于将右侧表达式的值赋给左侧的变量。这其实是一个笼统的概括,并不准确,正确的说法应该分为四个步骤:

  1. 找到变量 a 的内存地址,准备赋值。
  2. 运算 = 右侧表达式的代码,得到要赋值的数据。
  3. 将右侧运算的数据放入之前找到的内存地址
  4. 返回整个表达式的结果,即左侧变量的新值。

前面三步都很好理解的,那第四步怎么理解呢?来看看这个简单的代码:

var a 
console.log(a = 10); // 10

这段代码输出结果为10, 有些小伙伴们可能会认为我们在输出变量 a,其实并不是,我们输出的是 a = 10 这个表达式的返回结果。好了清楚了这四步之后,我们再来看这个面试题就清晰多了。

解题思路

对于 var a = { n: 1 } var b = a 不用多说什么,会形成这样一个内存的结构:

带你迈过js赋值运算的坑(附带面试题)

接下来看关键的一步 a.x = a = { n: 2 } 连续赋值,我们先从总体来看,这其实就是一个赋值运算,将右侧表达式的值赋给左侧的变量,这样我们就能套用上面讲的那四步来做了。

首先找到 a.x 的内存空间,我们发现这里好像不存在 a.x 的内存空间,但 js 是允许 动态添加对象属性 ,所以我们直接创建一块内存空间就好了。

带你迈过js赋值运算的坑(附带面试题)

接下来第二步:运算 = 右侧表达式的代码,这时我们会发现,右侧表达式还是一个赋值,所以我们接着套用那四步,找到 a 的内存空间,算出右侧表达式,结果为一个对象,第三步,将对象的地址值放进去。所以内存结构就为:

带你迈过js赋值运算的坑(附带面试题)

这时候注意,别忘了还有第四步,返回整个表达式的结构。在这里,整个表达式的结果是什么?就是 { n: 2 } 这个对象的地址。所以它会将这个地址赋值给表达式左边的 a.x。最终这个内存结构为:

带你迈过js赋值运算的坑(附带面试题)

看着这个图,我们再来判断 console.log(a.x) console.log(b.x) 就很简单了。

总结

恭喜你又解决了一道面试题,看完面试题之后,我们可以拓展了解下 js 中的赋值运算。赋值运算符是=,简单来说赋值运算是将一个值赋给一个变量的过程,以下是一些基本的赋值运算示例:

  1. 简单赋值

let a = 10; // 将数字10赋给变量a

let b = "Ywis"; // 将字符串"Ywis"赋给变量b

  1. 复合赋值
  • 加等于(+=)
  • 减等于(-=)
  • 乘等于(*=)
  • 除等于(/=)
  • 模等于(%=)
  • 位与等于(&=)
  • 位或等于(|=)
  • 位异或等于(^=)
  • 左移等于(<<=)
  • 右移等于(>>=)
  • 无符号右移等于(>>>=)
let x = 5;
x += 3; // x现在是8
x -= 1; // x现在是7
x *= 2; // x现在是14
x /= 4; // x现在是3.5
x %= 2; // x现在是1
......
  1. 并行赋值:可以在一行中对多个变量进行赋值。

let x, y, z

x = y = z = 10 // x, y, z都被赋值为10

  1. 解构赋值:从数组或对象中提取值并赋给变量。

let [a, b] = [1, 2]; // a是1,b是2

let {name, age} = {name: "Ywis", age: 18}; // name是"Ywis",age是18

  1. 默认值赋值:当尝试赋值的变量未定义或值为undefined时,可以使用默认值。

let a = 10; let b;

let c = a ?? 20; // c为10,因为a不是null或undefined

let d = b ?? 20; // d为20,因为b为undefined

最后祝你也祝我在今后日子里能够登高望远,心向彼岸。

转载自:https://juejin.cn/post/7370275556904468489
评论
请登录