1. new Array()和map
const array = new Array(5).map((item) => {
return item = {
name: '1'
}
})
console.log(array);//[] length为5的空数组
2. 数组扁平化
let arr = [1, [2, [3, [4]]]]
const _flatten = arr => {
// 补全代码
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? _flatten(cur) : cur)
}, [])
}
console.log(_flatten(arr))
3. 连续赋值(a=b=c)
let obj = {
num1: 117
}
let res = obj;
obj.child = obj = { num2: 935 };
var x = y = res.child.num2;
console.log(obj.child);//undefined
console.log(res.num1);//117
console.log(y);//935
连续赋值:从右至左永远只取等号右边的表达式结果赋值给等号左侧
连续赋值不可以拆开写,为什么?
js内部为了保证赋值语句的正确,会在一条赋值语句执行前,先把所有要赋值的引用地址取出一个副本,再依次赋值。
obj.child = obj = { num2: 935 };的逻辑是
- 在执行前,会先将obj.child和obj中obj的引用地址都取出来,此时他们指向{ num1: 117}
- 在内存中创建一个新对象{ num2: 935 }
- 执行obj = { num2: 935 },将obj的引用从{ num1: 117}改为指向新的 { num2: 935 }
- 执行obj.child = obj,此时obj已经有了新的对象,而obj.child因为执行前保留了原引用,所以
给原对象新增一个属性child。 { num1: 117,child :{ num2: 935 }}
-
语句执行结束,原对象由{num1: 117}变成 { num1: 117,child :{ num2: 935 }},而原对象因为无人再引用他,所以被GC回收,当前a指向新对象{ num2: 935 }
-
所以再执行obj.child,自然就是undefined了