ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第3章 变量的解构赋值

2022-05-11 18:32:05  阅读:172  来源: 互联网

标签:console 变量 hzh js 解构 log 赋值 hzh2 hzh1


3.1 数组的解构赋值

3.1.1 基本用法

ES6 允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称为解构(Destructuring)。

以前,为变量赋值只能直接指定值。

// hzh.js

let hzh1 = 1;
let hzh2 = 2;
let hzh3 = 3;

ES6允许写成下面这样。

// hzh.js

let [hzh1, hzh2, hzh3] = [1, 2, 3];

上面的代码表示,可以从数组中提取值,按照对应位置对变量赋值。

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。

// hzh.js

let [hzh1, [[hzh2], hzh3]] =[ 1,[[2], 3] ];
console.log("hzh1 = " + hzh1);
console.log("hzh2 = "+ hzh2);
console.log("hzh3 = " + hzh3);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 1
hzh2 = 2
hzh3 = 3

[Done] exited with code=0 in 0.173 seconds
// hzh.js

let [ , , third ,] = ["尤雨溪", "人世间", "黄子涵"];
console.log("third = " + third);
[Running] node "e:\HMV\Babel\hzh.js"
third = 黄子涵

[Done] exited with code=0 in 0.83 seconds
// hzh.js

let [hzh1, , hzh3] = [1, 2, 3];
console.log("hzh1 = " + hzh1);
console.log("hzh3 = " + hzh3);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 1
hzh3 = 3

[Done] exited with code=0 in 0.205 seconds
// hzh.js

let [hzh1, ...hzh2] = [1, 2, 3, 4];
console.log("输出hzh1的值:");
console.log(hzh1);
console.log("输出hzh2的值:");
console.log(hzh2);
[Running] node "e:\HMV\Babel\hzh.js"
输出hzh1的值:
1
输出hzh2的值:
[ 2, 3, 4 ]

[Done] exited with code=0 in 0.179 seconds
// hzh.js

let [hzh1, hzh2, ...hzh3] = ['黄子涵'];
console.log("输出hzh1的值:");
console.log(hzh1);
console.log("输出hzh2的值:");
console.log(hzh2);
console.log("输出hzh3的值:");
console.log(hzh3);
[Running] node "e:\HMV\Babel\hzh.js"
输出hzh1的值:
黄子涵
输出hzh2的值:
undefined
输出hzh3的值:
[]

[Done] exited with code=0 in 0.201 seconds

如果解构不成功,变量的值就等于undefined。

// hzh.js

let [hzh1] = [];
let [hzh2, hzh3] = [1];
console.log("hzh1 = "+ hzh1);
console.log("hzh2 = "+ hzh2);
console.log("hzh3 = "+ hzh3);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = undefined
hzh2 = 1
hzh3 = undefined

[Done] exited with code=0 in 0.198 seconds

以上两种情况都属于解构不成功,hzh和hzh3的值都会等于undefined。

另一种情况是不完全解构,即等号左边的模式只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

// hzh.js

let [hzh1, hzh2] = [1, 2, 3];
let [hzh3, [hzh4], hzh5] = [3, [4, '不解构'], 5];
console.log("hzh1 = "+ hzh1);
console.log("hzh2 = "+ hzh2);
console.log("hzh3 = "+ hzh3);
console.log("hzh4 = "+ hzh4);
console.log("hzh5 = "+ hzh5);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 1
hzh2 = 2
hzh3 = 3
hzh4 = 4
hzh5 = 5

[Done] exited with code=0 in 0.226 seconds

上面两个例子都属于不完全解构,但是可以成功。

如果等号的右边不是数组(或者严格来说不是可遍历的结构),那么将会报错。

// hzh.js
// 报错的例子

let [hzh1] = 1;
console.log(hzh1);
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
let [hzh1] = 1;
             ^

TypeError: 1 is not iterable
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.168 seconds
// hzh.js
// 报错的例子

let [hzh2] = false;
console.log(hzh2);
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
let [hzh2] = false;
             ^

TypeError: false is not iterable
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.169 seconds
// hzh.js
// 报错的例子

let [hzh3] = NaN;
console.log(hzh3);
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
let [hzh3] = NaN;
             ^

TypeError: NaN is not iterable
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.194 seconds
// hzh.js
// 报错的例子

let [hzh4] = undefined;
console.log(hzh4);
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
let [hzh4] = undefined;
             ^

TypeError: undefined is not iterable
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.186 seconds
// hzh.js
// 报错的例子

let [hzh5] = null;
console.log(hzh5);
[Running] node "e:\HMV\Babel\tempCodeRunnerFile.js"
e:\HMV\Babel\tempCodeRunnerFile.js:4
let [hzh5] = null;
             ^

TypeError: null is not iterable
    at Object.<anonymous> (e:\HMV\Babel\tempCodeRunnerFile.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.169 seconds
// hzh.js
// 报错的例子

let [hzh6] = {};
console.log(hzh6);
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
let [hzh6] = {};
             ^

TypeError: {} is not iterable
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.17 seconds

上面的语句都会报错,因为等号右边的值或是转为对象以后不具备 Iterator 接口(前五个表达式),或是本身就不具备 Iterator 接口(最后一个表达式)。

对于 Set 结构,也可以使用数组的解构赋值。

// hzh.js

let [hzh1, hzh2, hzh3] = new Set(['黄子涵', '尤雨溪', '人世间']);
console.log("hzh1 = " + hzh1);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 黄子涵

[Done] exited with code=0 in 0.506 seconds

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

// hzh.js

function* fibs() {
    let hzh1 = 1;
    let hzh2 = 2;
    while(true) {
        yield hzh1;
        [hzh1, hzh2] = [hzh2, hzh1 + hzh2];
    }
}

let [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth);
[Running] node "e:\HMV\Babel\hzh.js"
13

[Done] exited with code=0 in 0.176 seconds

上面的代码中,fibs 是一个 Generator 函数,原生具有 Iterator 接口。解构赋值会依次从这个接口中获取值。

上面关于fibs函数这部分不是很懂。

3.1.2 默认值

// hzh.js

let [hzh1 = true] = [];
console.log("hzh1 = " + hzh1);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = true

[Done] exited with code=0 in 0.194 seconds
// hzh.js

let [hzh2, hzh3 = 'b'] = ['黄子涵是帅哥!'];
let [hzh4, hzh5 = 'c'] = ['黄子涵是靓仔!', undefined];
console.log("hzh2 = " + hzh2);
console.log("hzh3 = " + hzh3);
console.log("hzh4 = " + hzh4);
console.log("hzh5 = " + hzh5);
[Running] node "e:\HMV\Babel\hzh.js"
hzh2 = 黄子涵是帅哥!
hzh3 = b
hzh4 = 黄子涵是靓仔!
hzh5 = c

[Done] exited with code=0 in 0.192 seconds

注意

ES6 内部使用严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效。

// hzh.js

let [hzh1 = 1] = [undefined];
let [hzh2 = 2] = [null];
console.log("hzh1 = " + hzh1);
console.log("hzh2 = " + hzh2);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 1
hzh2 = null

[Done] exited with code=0 in 0.576 seconds

上面的代码,如果一个数组成员,默认值就不会生效,因为 null 不严格相等 undefined。

如果默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到时才会求值。

// hzh.js

function huangzihan() {
    console.log('黄子涵');
}

let [hzh = huangzihan()] = [1];
[Running] node "e:\HMV\Babel\hzh.js"

[Done] exited with code=0 in 0.594 seconds

上面的代码中,因为 x 能取到值,所以函数 f 根本不会执行。上面的代码其实等价于下面的代码。

// hzh.js

let hzh;
if([1][0] === undefined) {
    hzh = huangzihan();
} else {
    hzh = [1][0];
}
[Running] node "e:\HMV\Babel\tempCodeRunnerFile.js"

[Done] exited with code=0 in 0.194 seconds

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

// hzh.js

let [hzh1 = 1, hzh2 = hzh1] = [];
console.log("hzh1 = " + hzh1);
console.log("hzh2 = " + hzh2);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 1
hzh2 = 1

[Done] exited with code=0 in 0.176 seconds
// hzh.js

let [hzh3 = 3, hzh4 = hzh3] = [2];
console.log("hzh3 = " + hzh3);
console.log("hzh4 = " + hzh4);
[Running] node "e:\HMV\Babel\hzh.js"
hzh3 = 2
hzh4 = 2

[Done] exited with code=0 in 0.196 seconds
// hzh.js

let [hzh5 = 5, hzh6 = hzh5] = [1, 2];
console.log("hzh5 = " + hzh5);
console.log("hzh6 = " + hzh6);
[Running] node "e:\HMV\Babel\hzh.js"
hzh5 = 1
hzh6 = 2

[Done] exited with code=0 in 0.179 seconds
// hzh.js

let [hzh7 = hzh8, hzh8 = 8] = [];
console.log("hzh7 = " + hzh7);
console.log("hzh8 = " + hzh8);
[Running] node "e:\HMV\Babel\tempCodeRunnerFile.js"
e:\HMV\Babel\tempCodeRunnerFile.js:3
let [hzh7 = hzh8, hzh8 = 8] = [];
            ^

ReferenceError: Cannot access 'hzh8' before initialization
    at Object.<anonymous> (e:\HMV\Babel\tempCodeRunnerFile.js:3:13)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.23 seconds

上面最后一个表达式之所以会报错,是因为 hzh7 用到默认值 hzh8 时,hzh8 还没有声明。

3.2 对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

// hzh.js

let { hzh1, hzh2 } = { hzh1: "黄子涵", hzh2: "尤雨溪" };
console.log("hzh1 = " + hzh1); 
console.log("hzh2 = " + hzh2); 
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 黄子涵
hzh2 = 尤雨溪

[Done] exited with code=0 in 0.229 seconds

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值。

// hzh.js

let { hzh2, hzh1 } = { hzh1: "黄子涵", hzh2: "尤雨溪" };
console.log("hzh1 = " + hzh1); 
console.log("hzh2 = " + hzh2); 
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 黄子涵
hzh2 = 尤雨溪

[Done] exited with code=0 in 0.196 seconds
// hzh.js

let { hzh2 } = { hzh1: "黄子涵", hzh2: "尤雨溪" };
console.log("hzh3 = " + hzh3); 
[Running] node "e:\HMV\Babel\hzh.js"
e:\HMV\Babel\hzh.js:4
console.log("hzh3 = " + hzh3); 
                        ^

ReferenceError: hzh3 is not defined
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:4:25)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.171 seconds

上面代码的第一个例子中,等号左边的两个变量的次序与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于 undefined 。

如果变量名与属性名不一致,必须写成下面这样

// hzh.js

let { hzh1: hzh3 } = { hzh1: "黄子涵", hzh2: "尤雨溪" };
console.log("hzh3 = " + hzh3); 
[Running] node "e:\HMV\Babel\hzh.js"
hzh3 = 黄子涵

[Done] exited with code=0 in 0.203 seconds
// hzh.js

let huangzihan = { hzh1: '黄子涵', hzh2: '尤雨溪'};
let { hzh1: h, hzh2: z} = huangzihan;
console.log("hzh1对象的h属性:" + h);
console.log("hzh2对象的z属性:" + z);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1对象的h属性:黄子涵
hzh2对象的z属性:尤雨溪

[Done] exited with code=0 in 0.194 seconds

实际上说明,对象的解构赋值是下面形式的简写。

// hzh.js

let { hzh1: hzh1, hzh2: hzh2} = { hzh1: '黄子涵', hzh2: '尤雨溪'};
console.log("hzh1 = " + hzh1);
console.log("hzh2 = " + hzh2);
[Running] node "e:\HMV\Babel\hzh.js"
hzh1 = 黄子涵
hzh2 = 尤雨溪

[Done] exited with code=0 in 0.2 seconds

也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者。

// hzh.js

let { hzh1: hzh3} = { hzh1: '黄子涵', hzh2: '尤雨溪'};
console.log("hzh3 = " + hzh3);
console.log("hzh1 = " + hzh1);
[Running] node "e:\HMV\Babel\hzh.js"
hzh3 = 黄子涵
e:\HMV\Babel\hzh.js:5
console.log("hzh1 = " + hzh1);
                        ^

ReferenceError: hzh1 is not defined
    at Object.<anonymous> (e:\HMV\Babel\hzh.js:5:25)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

[Done] exited with code=1 in 0.176 seconds

上面的代码中,hzh1是匹配的模式,hzh3才是变量。真正被赋值的是变量 hzh3,而不是模式 hzh1。

与数组一样,解构也可以用于嵌套结构的对象。



注意,这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样。

上面的代码有三次解构赋值,分别是对 loc、start、line 三个属
性的解构赋值。需要注意的是,最后一次对line属性的解构赋值
之中,只有line是变量,loc和start都是模式,不是变量。
下面是嵌套赋值的例子。

3.3 字符串的解构赋值

3.4 数值和布尔值的解构赋值

3.5 函数参数的解构赋值

3.6 圆括号问题

3.6.1 不能使用圆括号的情况

3.6.2 可以使用圆括号的情况

3.7 用途

标签:console,变量,hzh,js,解构,log,赋值,hzh2,hzh1
来源: https://www.cnblogs.com/Huang-zihan/p/16248768.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有