解构赋值及其原理
解构赋值:其实就是分解出一个对象的解构,分成两个步骤:
原理:ES6 变量的解构赋值本质上是“模式匹配”, 只要等号两边的模式相同,左边的变量就会被赋予匹配的右边的值,如果匹配不成功变量的值就等于 undefined
注意:如果剩余参数是对应的值为 undefined,则赋值为[],因为找不到对应值的时候,是通过 slice 截取的,如下:
let [a, ...reset] = [1];
console.log(a, reset); //1,[]
其转成 ES5 的原理如下:
var _ref = [1],
a = _ref[0],
reset = _ref.slice(1);
console.log(a, reset); //1,[]
总结
非数组解构成数组(重点,难点)
一条原则:要解构成数组的前提:如果等号右边,不是数组(严格地说,不是可遍历的解构),则直接报错,例如:
为什么?转成 ES5 看下原理就一清二楚了:
var _ = 1,
foo = _[0]; //报错
var _false = false,
foo1 = _false[0]; //报错
var _NaN = NaN,
foo2 = _NaN[0]; //报错
var _undefined = undefined,
foo3 = _undefined[0]; //报错
var _ref = null;
foo4 = _ref[0]; //报错
var _ref2 = {},
foo5 = _ref2[0]; //报错
let [a, b = 'default'] = [1];
console.log(a, b); //1,'default'
function f() {
console.log('aaa'); //'aaa'
}
let [a, x = f()] = [1];
console.log(a, x); //1,undefined
console.log([1][1] === undefined); //true
{}是块还是对象?
当我们写解构赋值的时候,很容易犯一个错误——{}的作用是块还是对象混淆,举例如下:
//举例一:
let {
a
} = {
a: "a"
};
console.log(a); //'a',这个很简单
//很多人觉得,以下这种写法也是可以的:
let a; {
a
} = {
a: "a"
}; //直接报错,因为此时a已经声明过了,在语法解析的时候,会将这一行的{}看做块结构,而“块=对象”,显然是语法错误,所以正确的做法是不将大括号写在开头,如下:
let a;
({
a
} = {
a: "a"
})
注意:字符串有一个属性 length,也可以被解构出来,但是要注意,解构属性一定是对象解构
let {
length
} = "hello";
console.log(length); //5
来源整理自:vue3js.cn 面试官系列



