关于解构赋值的一些意想不到的坑

今天群里有个人问了一个问题,问我们为什么报错,代码如下

js 复制代码
var arr = [1,2,3,4,5,6,7,8,9,10]
for(let i = arr.length; i > 0; i--) {
    let index = Math.floor(Math.random() * i)
    // console.log(i, index);
    [arr[i-1], arr[index]] = [arr[index], arr[i-1]]
    // ReferenceError: Cannot access 'index' before initialization
}
console.log(arr)

我乍一看,这能报错?不应该啊,怎么能呢,于是我特意复制下来跑了一下,嘿,还真是

关于ReferenceError: Cannot access 'xxx' before initialization的报错,往往和暂时性死区有关,但我看了看顺序,是先定义的index啊,没有错。

抱着求知的心态,上网查了一些文章,都没有提到这种问题,于是只能去看ecma规范,但对不起,我英语太差了,我就连在哪都没找到。

后来我想起自己曾经遇到过类似的问题,只不过是在解构对象的时候遇到的

大概是这样的操作

js 复制代码
let a = xxx

({
    a: this.options.a,
    b: this.options.b,
    ......
} = /*一个对象*/ ?? {})

当时也报了错,我就想起来了

js中是允许语句不使用;结尾的,许多小伙伴可能养成了这个习惯,虽然不写分号有时候确实很爽很轻松,也是一些企业的规范,但是等到流泪的时候可就知道惨了。

只需要将上述结构赋值的代码的前面一个语句加上分号,就可以解决这个问题

相当于把一个语句拆开了

什么?你问我怎么就成同一个语句了?

我没记错的话,js在执行的时候是会忽略换行符的吧,或者说这个换行符没那么重要,所以我们平时看到的很多库打包出来的min.js文件都是只有一行的然后通过分号分割语句。

如果把上述代码换行内容忽视掉,就变成了这个样子,只放了部分代码

js 复制代码
    let index = Math.floor(Math.random() * i)[arr[i-1], arr[index]] = [arr[index], arr[i-1]]

这不报错谁报错啊,根据等号从右到左的运算顺序,不就是访问了暂时性死区嘛

所以加上分号,问题就引刃而解了。

想当年因为先学c++和java的缘故,总是养成写分号的习惯,在切图仔里面似乎成为了一个异类,现在知道了吧,养成写分号的好习惯啊,呜呜呜呜

最后附上修改后的代码

js 复制代码
var arr = [1,2,3,4,5,6,7,8,9,10]
for(let i = arr.length; i > 0; i--) {
    let index = Math.floor(Math.random() * i);
    // console.log(i, index);
    [arr[i-1], arr[index]] = [arr[index], arr[i-1]]
    // ReferenceError: Cannot access 'index' before initialization
}
console.log(arr)

更好笑的是,这哥们明显是想通过console测试一下的,结果他发现console就不报错,不console就报错,这是真的折磨哈哈哈哈哈哈

养成语句加分号的好习惯!! 从你我做起!

相关推荐
Lingxing13 天前
深入浅出:从JS的new运算符到手写ES5/ES6版实现
前端·javascript·ecmascript 6
学吧别真挂了15 天前
全网最走心!Symbol知识点+实战避坑全解析🎯
javascript·ecmascript 6
大龄大专大前端17 天前
JavaScript闭包的认识/应用/原理
前端·javascript·ecmascript 6
鱼樱前端23 天前
Vue3+TS+Vant 上拉加载下拉刷新框架
前端·vue.js·ecmascript 6
抱走白菜2 个月前
JS高级:手写一个Promise
前端·面试·ecmascript 6
Bigger3 个月前
面试官问:了解哪些最新的 ES 新特性?——这样回答更好!
前端·javascript·ecmascript 6
午后书香3 个月前
什么是数据劫持与事件委托?有什么用?
前端·javascript·ecmascript 6
似Yu非4 个月前
一文掌握 ECMAScript 的进化史:从 ES3 到 ES2024 的特性与用法
ecmascript 6
poloma5 个月前
五千字长文搞清楚 Blob File ArrayBuffer TypedArray 到底是什么
前端·javascript·ecmascript 6
卡布鲁6 个月前
Promise深入理解:探索相关高级用法
javascript·ecmascript 6