让学习“上瘾”,成为更好的自己!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>对象的解构赋值</title>
</head>
<body>
<script>
// (1) 对象的解构和数组的有一个不同的地方: 数组 --> 数组的元素是按次序排序的,变量的取值是由他的位置决定的
// 对象 --> 对象的属性没有次序,变量必须与属性同名才能得到正确的值
// let {bar, foo} = {
// foo: 'aaaa',
// bar: 'bbb'
// };
// console.log(foo);
// console.log(bar);
// let {baz} = {
// foo: 'aaaa',
// bar: 'bbb'
// };
// console.log(baz); // undefined
// (2) 如果变量名与属性名不一致,必须如下书写:
// var {foo: baz} = {
// foo: 'aaa',
// bar: 'bbb'
// };
// console.log(baz); // aaa
// let obj = {
// first: 'hello',
// last: 'world'
// };
// let {first: f, last: l} = obj;
// console.log(f);
// console.log(l);
// 【总结】对象的解构赋值本质上是下面形式的简写!!!
// let {foo: foo, bar: bar} = {
// foo: 'aaa',
// bar: 'bbb'
// };
// (3) 对象的解构赋值的内部机制是先找到同名的属性,然后在赋值给对应的变量,真正被赋值的是后者,而不是前者
// var {foo: baz} = {
// foo: 'aaa',
// bar: 'bbb'
// };
// console.log(baz);
// console.log(foo); // foo is not defined
// (4) 与数组一样,解构也可以用于嵌套结构的对象
// let obj = {
// p: [
// 'Hello',
// {y: 'World'}
// ]
// };
// let { p: [x, {y}]} = obj; // 这里的p是"模式",不是变量,不会被赋值
// console.log(x); // Hello
// console.log(y); // World
// 【改变】 给p也赋一个值
// let { p, p: [x, {y}]} = obj;
// console.log(p); // [” Hello ”,( y :” World ”}]
// another example:
// var node = {
// loc: {
// start: {
// line: 1,
// colume: 5
// }
// }
// };
// var {loc, loc:{start}, loc: {start: {line}}} = node; // line是变量,loc and start 都是模式,不是变量
// console.log(line); // 1
// console.log(loc); // 模式
// console.log(start); // {line: 1, colume: 5}
// 嵌套赋值:
// let obj = {};
// let arr = [];
// ({foo: obj.prop, bar: arr[0]} = {foo: 123, bar: true});
// console.log(obj); // {prop: 123}
// console.log(arr); // [true]
// (5) 对象的解构也可以指定默认值 --> 本质是对解构出来的变量赋默认值,而不是对整个对象!!
// var {x = 3} = {};
// console.log(x); // 3
// var {x, y = 5} = {x: 1};
// console.log(x, y); // 1, 5
// var {x: y = 3} = {};
// console.log(y); // 3
// var {x: y = 3} = {x: 5};
// console.log(y); // 5
// var {message: msg = 'Something went wrong!'} = {};
// console.log(msg);
// 默认值生效的条件是:对象的属性值严格等于undefined
// var {x = 3} = {x: undefined};
// console.log(x); // 3
// var {x = 3} = {x: null};
// console.log(x); // null --> x的属性为null,不严格等于undefined,默认值不生效!!
// (6) 如果解构失败,变量的值等于undefined
// let {foo} = {bar: 'baz'};
// console.log(foo); // undefined
// (7) 如果解构模式是“嵌套的对象”,而且子对象所在的父属性不存在,则会报错
// let {foo: {bar}} = {baz: 'baz'}; // 左边对象的foo属性是一个子对象,而foo等于undefined,此时取子属性会报错
// let _tmp = {baz: 'baz'};
// _tmp.foo.bar; // 报错
// (8) 将一个已经声明的变量用于解构赋值,要注意:
// let x;
// {x} = {x: 1}; // 报错 --> 只有不将大括号放在行首,才能避免JavaScript将其解释为代码块
// 【正确写法】 --> 多加了个“圆括号” --> 圆括号与解构赋值的关系(见第6节-圆括号问题)
let x;
({x} = {x: 1});
console.log(x);
// (8) 解构赋值允许等号左边的模式之中不放置任何变量名
({} = [true, false]);
({} = []);
({} = 'avf');
// 表达式毫无意义,但语法时正确的
// (9) 对象的解构赋值可以很方便地将现有的对象的方法赋值给某个变量
let {log, sin, cos} = Math;
console.log(sin);
// (10) 数组本质也是对象,因此可以对数组进行对象属性的解构
let arr = [1, 2, 4];
console.log(arr);
let {0: first, [arr.length - 1]: last} = arr;
let {[0]: first, [arr.length - 1]: last} = arr; // 方括号写法属于“属性名表达式”(第9章)
console.log(first);
console.log(last);
</script>
</body>
</html>