(JS用 “数组解构“ 的方式)交换两个变量时的一些问题

今天在写算法时,本人经常用ES6的解构方式去交换一些变量,但是由于本人的编码规范是不喜欢加分号的,所以翻车了。于是我做了很多测试,这让我更加明白了什么时候必须要加分号,什么时候可以不用加。

翻车例题

以下有这么一段代码

let arr1 = [1,2,3]
let arr2 = [4,5,6,7]
let lenA = arr1.length
let lenB = arr2.length

if(lenA < lenB) {
	[arr1, arr2] = [arr2, arr1]
	[lenA, lenB] = [lenB, lenA]
}

// arr1 现在是什么? arr2 现在是什么?
// lenA 等于几? lenB等于几?

问题

  1. arr1 现在是什么? arr2 现在是什么?
  2. lenA 等于几? lenB等于几?

有用过数组交换变量的同学,可能认为他们成功的交换了, arr1就等于arr2嘛,arr2就等于arr1吗,lenA和lenB也交换了呀。然而并非如此!!

它们没有正常交换,甚至中途还发生了中断交换。

控制台的输出结果是:

arr1 = 4, arr2 = 3 神奇吧!!!
lenA = 3, lenB = 4 !!!根本没有交换

于是

我又用了个例子测试一下

let a = 1, b = 2, c = 3, d =4
if(true) {
    [a, b] = [b, a]
    [c, d] = [d, c]
}

输出还是 a = 4, b = 3 是后面的交换,相等于 [a, b] = [d, c],我一时之间怀疑自己多年学习的JavaScript成果。
为了找原因和解决这个问题,我开始进行了debug操作。
首先来两个log看看

if(true) {
    [a, b] = [b, a]
    console.log('a: ', a, 'b: ', b)
    [c, d] = [d, c]
    console.log('c: ', c, 'd: ', d)
}

我尝试这么做,结果报错了,大年初六,看到红色的我也是很兴奋的,至少我们找到了问题源头。
在这里插入图片描述
在这里,他们的交换失败了。

头绪

一开始看到这个红色的东西,我个人觉得这可能是作用域的小问题。
接着我就把他们两个交换拆开放在两个块级作用域分别去执行。
有了下面这个代码

if(true) {
	[a, b] = [b, a]
}

if(true) {
	[c, d] = [d, c]
}

此时的我认为,这肯定交换成功啊! 确实,交换成功了!!!
在这里插入图片描述
到了这里,我明白了我为什么会出现这个Bug。平时写代码时,我们是懒得把两条同样逻辑的代码写在两个块级作用域,我们就是要写在一起!

解决: 分号!!!

我就把分号加上,看看会发生什么不一样的事情,结果是真的妙啊!!

if(true) {
    [a, b] = [b, a];
    [c, d] = [d, c];
}

注意:上面代码都加上分号了!!

执行输出后的结果,成功的交换了,而且不会报错!
a = 2, b = 1, c = 4, d = 3
此时我想到了JavaScript的词法作用域的真理:在于声明的时候!
我猜想引擎在进行解析提取AST时,执行的RHS(retrieve his source value)取得它的源值时,可能是通过分号或换行符\n来判断结束RHS查询结束的。

关于引擎怎么解析提取查询变量的过程,推荐看《你不知道的JavaScript》这本书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值