我是小又又,住在武汉,做了两年新媒体,准备用 6 个月时间转行前端。
今日学习目标
昨天基于搜索来基础学习严格模式.所以今天就开始基础学习解构,又是适合学习的一天,加油,小又又!!!!
今天在一篇文章中,学习了一个简洁调用
console.log的方法,之前在示例文章中用的很多,感觉重复代码很多,感觉文章中这种用法,还蛮不错的~~~~
字符串
转为数组解构
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
(function (log) {
const [a, b, c, d, e] = 'hello';
log(a); // "h"
log(b); // "e"
log(c); // "l"
log(d); // "l"
log(e); // "o"
})(console.log)

感觉很神奇~~~~~,也就是说我之前学习的
String数据结构其实也可以转成数组这样~~~
解构字符串长度
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
(function (log) {
const {
length: len
} = 'hello';
log(len); // 5
})(console.log)

感觉很神奇~~~~~,也就是说我之前学习的
String数据结构其实也可以转成对象这样~~~
数值和布尔值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
(function (log) {
const {
toString: s1
} = 123;
log(s1 === Number.prototype.toString); // true
const {
toString: s2
} = true;
log(s2 === Boolean.prototype.toString); // true
})(console.log)

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s1和变量s2都能取到值。
数值数据类型有学习过,布尔值数据类型好像没有学习过~~~
数组
基础用法
完全解构
(function (log) {
// 基础数组解构
const [a, b, c] = [1, 2, 3];
log(a); // 1
log(b); // 2
log(c); // 3
// 嵌套数组解构
const [foo, [[bar], baz]] = [1, [[2], 3]];
log(foo); // 1
log(bar); // 2
log(baz); // 3
// 指定索引解构
const [ , , third] = ["foo", "bar", "baz"];
log(third); // "baz"
const [x, , y] = [1, 2, 3];
log(x); // 1
log(y); // 3
const [head, ...tail] = [1, 2, 3, 4];
log(head); // 1
log(tail); // [2, 3, 4]
const [e, f, ...g] = ['a'];
log(e); // "a"
log(f); // undefined
log(g); // []
})(console.log)

这个里面好像又出现
...,感觉要找时间学习一下~~~
不完全解构
另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
(function (log) {
const [x, y] = [1, 2, 3];
log(x); // 1
log(y); // 2
const [a, [b], d] = [1, [2, 3], 4];
log(a); // 1
log(b); // 2
log(d); // 4
})(console.log)

上面两个例子,都属于不完全解构,但是可以成功。
所以,不完整解构,就是左边的变量个数和右边的不一样~~~~
设置默认值
基础使用
解构赋值允许指定默认值。
(function (log) {
const [foo = true] = [];
log(foo); // true
const [x, y = 'b'] = ['a'];
log(x);// 'a'
log(y);// 'b'
const [a, b = 'b'] = ['a', undefined];
log(a);// 'a'
log(b);// 'b'
})(console.log)

不太清楚这个默认值的使用场景
使用表达式
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
(function (log) {
function f() {
console.log('aaa');
}
const [x = f()] = [1];
log(x);// 1
})(console.log)

上面代码中,因为x能取到值,所以函数f根本不会执行。上面的代码其实等价于下面的代码。
(function (log) {
let x;
if ([1][0] === undefined) {
x = f();
} else {
x = [1][0];
}
log(x);// 1
})(console.log)

这个说明有些看不太懂~~~~
引用其他变量值
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
(function (log) {
const [x1 = 1, y1 = x1] = [];
log(x1);// 1
log(y1);// 1
const [x2 = 1, y2 = x2] = [2];
log(x2);// 2
log(y2);// 3
const [x3 = 1, y3 = x3] = [1, 2];
log(x3);// 1
log(y3);// 2
const [x4 = y4, y4 = 1] = []; // Cannot access 'y4' before initialization
})(console.log)

上面最后一个表达式之所以会报错,是因为x4用y4做默认值时,y4还没有声明。
感觉这个应该要注意一下~~~
注意事项
解构不成功
如果解构不成功,变量的值就等于undefined。
const [foo] = [];
const [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。
不可遍历结构
如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。
(function (log) {
// 报错
const [foo1] = 1;// TypeError: 1 is not iterable
const [foo2] = false;// TypeError: false is not iterable
const [foo3] = NaN;// TypeError: NaN is not iterable
const [foo4] = undefined;// TypeError: undefined is not iterable
const [foo5] = null;// TypeError: null is not iterable
const [foo6] = {};// TypeError: {} is not iterable
})(console.log)
上面的语句都会报错,因为等号右边的值,要么转为对象以后不具备 Iterator 接口(前五个表达式),要么本身就不具备 Iterator 接口(最后一个表达式)。
函数
基础用法
基础使用
函数的参数也可以使用解构赋值。
(function (log) {
function add([x, y]) {
return x + y;
}
log(add([1, 2])); // 3
})(console.log)

上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。
结合箭头函数使用
函数的参数也可以使用解构赋值。
(function (log) {
const arr = [
[1, 2],
[3, 4]
].map(([a, b]) => a + b);
log(arr); // [ 3, 7 ]
})(console.log)

设置默认值
函数参数的解构也可以使用默认值。
函数对象参数属性使用默认值
(function (log) {
function move({
x = 0,
y = 0
} = {}) {
return [x, y];
}
log(move({
x: 3,
y: 8
})); // [3, 8]
log(move({
x: 3
})); // [3, 0]
log(move({})); // [0, 0]
log(move()); // [0, 0]
})(console.log)

上面代码中,函数move的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。
函数对象参数使用默认值
(function (log) {
function move({
x,
y
} = {
x: 0,
y: 0
}) {
return [x, y];
}
log(move({
x: 3,
y: 8
})); // [3, 8]
log(move({
x: 3
})); // [3, undefined]
log(move({})); // [undefined, undefined]
log(move()); // [0, 0]
})(console.log)

上面代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
注意事项
undefined就会触发函数参数的默认值。
(function (log) {
const arr = [1, undefined, 3].map((x = 'yes') => x);
log(arr); // [ 1, 'yes', 3 ]
})(console.log)

今日学习总结

今日心情
今日主要是基于搜索来基础学习解构,这个希望明天学到更多的内容~~~~

本文使用 mdnice 排版