Rumah hujung hadapan web tutorial js 详解ECMAScript6变量的解构赋值

详解ECMAScript6变量的解构赋值

Feb 08, 2018 pm 01:07 PM
Tugasan

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring),本文主要和大家分享嵌套数组的解构例子,大家一起看看吧var [a, b, c] = [1, 2, 3];

这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

下面是一些使用嵌套数组进行解构的例子

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
Salin selepas log masuk

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

foo 的值都会等于 undefined

var [foo] = [];
var [bar, foo] = [1];
Salin selepas log masuk

不完全解构即等号左边的模式,只匹配一部分的等号右边的数组

let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
Salin selepas log masuk

如果等号的右边不是数组,那么将会报错。

// 报错let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
Salin selepas log masuk

解构赋值不仅适用于var命令,也适用于let和const命令

var [v1, v2, ..., vN ] = array;
let [v1, v2, ..., vN ] = array;
const [v1, v2, ..., vN ] = array;
Salin selepas log masuk

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

let [x, y, z] = new Set(["a", "b", "c"]);
x // "a"
Salin selepas log masuk

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

function* fibs() {
  var a = 0;
  var b = 1;
  while (true) {
  yield a;
   [a, b] = [b, a + b];
  }
}
var [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
Salin selepas log masuk

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

解构赋值允许指定默认值。

var [foo = true] = [];
foo // true
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'
Salin selepas log masuk

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

var [x = 1] = [undefined];
x // 1
var [x = 1] = [null];
x // null
Salin selepas log masuk

如果一个数组成员是 null ,默认值就不会生效,因为 null 不严格等于 undefined

function f() {
console.log('aaa');
}
let [x = f()] = [1];
//等价于
let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}
Salin selepas log masuk

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

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

let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError
Salin selepas log masuk

是因为 x 用到默认值 y 时, y 还没有声明

对象的解构赋值

var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
Salin selepas log masuk

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

var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
Salin selepas log masuk

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

var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
Salin selepas log masuk

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

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
Salin selepas log masuk

上面代码中,真正被赋值的是变量 baz ,而不是模式 foo

变量的声明和赋值是一体的。对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明
过,就会报错

let foo;
let {foo} = {foo: 1}; 
// SyntaxError: Duplicate declaration "foo"
let baz;
let {bar: baz} = {bar: 1}; 
// SyntaxError: Duplicate declaration "baz"
Salin selepas log masuk

因为 var 命令允许重新声明,所以这个错误只会在使用 let 和 const 命令时出现。如果没有第二个let命令,上面的代码就不会报错

let foo;
({foo} = {foo: 1}); // 成功
let baz;
({bar: baz} = {bar: 1}); // 成功
Salin selepas log masuk

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

var obj = {
  p: [
   "Hello",
   { y: "World" }
  ]
};
var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
Salin selepas log masuk

这时 p 是模式,不是变量,因此不会被赋值

var node = {
  loc: {
   start: {
     line: 1,
     column: 5
   }
  }
};
var { loc: { start: { line }} } = node;
line // 1
loc // error: loc is undefined
start // error: start is undefined
Salin selepas log masuk

只有 line 是变量, loc 和 start 都是模式,不会被赋值

嵌套赋值的例子。

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123}
arr // [true]
Salin selepas log masuk

对象的解构也指定默认值

var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var { message: msg = "Something went wrong" } = {};
msg // "Something went wrong"
Salin selepas log masuk

默认值生效的条件是,对象的属性值严格等于 undefined

var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null
Salin selepas log masuk

如果解构失败,变量的值等于 undefined

var {foo} = {bar: 'baz'};
foo // undefined
Salin selepas log masuk

解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错

// 报错
var {foo: {bar}} = {baz: 'baz'};
Salin selepas log masuk

等号左边对象的 foo 属性,对应一个子对象。该子对象的 bar 属性,解构时会报错。因为 foo 这时等于 undefined ,再取子属性就会报错

要将一个已经声明的变量用于解构赋值,必须非常小心

// 错误的写法
var x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正确的写法
({x} = {x: 1});
Salin selepas log masuk

因为JavaScript引擎会将 {x} 理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量

let { log, sin, cos } = Math;
Salin selepas log masuk

将 Math 对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多

字符串的解构赋值

字符串也可以解构赋值。此时字符串被转换成了一个类似数组的对象

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
Salin selepas log masuk

类似数组的对象都有一个 length 属性,因此还可以对这个属性解构赋值

let {length : len} = 'hello';
len // 5
Salin selepas log masuk

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
Salin selepas log masuk

数值和布尔值的包装对象都有 toString 属性,因此变量 s 都能取到值

解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
Salin selepas log masuk

函数参数的解构赋值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3
Salin selepas log masuk

函数参数的解构也可以使用默认值

function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
Salin selepas log masuk

函数 move 的参数是一个对象,通过对这个对象进行解构,得到变量 x 和 y 的值。如果解构失败, x 和 y 等于默认值

function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
Salin selepas log masuk

是为函数 move 的参数指定默认值,而不是为变量 x 和 y 指定默认值,所以会得到与前一种写法不同的结果。undefined 就会触发函数参数的默认值

圆括号问题

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道如果模式中出现圆括号怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号

不能使用圆括号的情况

1.变量声明语句中,不能带有圆括号

// 全部报错
var [(a)] = [1];
var {x: (c)} = {};
var ({x: c}) = {};
var {(x: c)} = {};
var {(x): c} = {};}
var { o: ({ p: p }) } = { o: { p: 2 } };
Salin selepas log masuk

2.函数参数中不能使用圆括号

// 报错
function f([(z)]) { return z; }
Salin selepas log masuk

3.赋值语句中,不能将整个模式,或嵌

套模式中的一层,放在圆括号之中

将整个模式放在模式之中,导致报错

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];
Salin selepas log masuk

将嵌套模式的一层,放在圆括号之中,导致报错

[({ p: a }), { x: c }] = [{}, {}];
Salin selepas log masuk

可以使用圆括号的况

赋值语句的非模式部分,可以使用圆括号

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
Salin selepas log masuk

首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性
质一致

用途

1.交换变量的值

[x, y] = [y, x];
Salin selepas log masuk

2.从函数返回多个值

// 返回一个数组
function example() {
  return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
  return {
   foo: 1,
   bar: 2
  };
}
var { foo, bar } = example();
Salin selepas log masuk

3.函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来

function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
Salin selepas log masuk

4.提取JSON数据

var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
Salin selepas log masuk

5.函数参数的默认值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};
Salin selepas log masuk

6.便利Map结构

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
Salin selepas log masuk

7.输入模块的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map")
Salin selepas log masuk

相关推荐:

ECMAScript6是什么?

ECMAScript6入门之Class对象的实例详解

ECMAScript6新增值比较函数Object.is_javascript技巧

Atas ialah kandungan terperinci 详解ECMAScript6变量的解构赋值. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk mendayakan salin dan tampal untuk mesin maya VMware Bagaimana untuk mendayakan salin dan tampal untuk mesin maya VMware Feb 21, 2024 am 10:09 AM

Anda boleh menyalin dan menampal teks dan fail dengan mudah antara mesin maya (VM) VMware dan sistem fizikal. Keupayaan ini membolehkan anda memindahkan imej, teks berformat dan tidak berformat dengan mudah, dan juga lampiran e-mel antara mesin maya dan sistem hos. Artikel ini akan menunjukkan kepada anda cara mendayakan ciri ini dan menunjukkan kaedah untuk menyalin data, fail dan folder. Cara Mendayakan Salin/Tampal dalam VMware VMware menyediakan tiga cara berbeza untuk menyalin data, fail atau folder daripada mesin maya ke mesin fizikal dan sebaliknya, seperti yang dijelaskan di bawah: Salin dan Tampal Elemen Seret dan Lepaskan Perkongsian Folder Ciri 1 ] Dayakan salinan -tampal menggunakan Alat VMware Anda boleh menggunakan papan kekunci jika pemasangan VMWare dan sistem pengendalian tetamu anda memenuhi keperluan

Bagaimana untuk menyalin halaman dalam Word Bagaimana untuk menyalin halaman dalam Word Feb 20, 2024 am 10:09 AM

Ingin menyalin halaman dalam Microsoft Word dan mengekalkan pemformatan? Ini adalah idea yang bijak kerana menduplikasi halaman dalam Word boleh menjadi teknik penjimatan masa yang berguna apabila anda ingin membuat berbilang salinan susun atur atau format dokumen tertentu. Panduan ini akan membimbing anda melalui proses langkah demi langkah menyalin halaman dalam Word, sama ada membuat templat atau menyalin halaman tertentu dalam dokumen. Arahan mudah ini direka untuk membantu anda mencipta semula halaman anda dengan mudah tanpa perlu bermula dari awal. Mengapa menyalin halaman dalam Microsoft Word? Terdapat beberapa sebab mengapa menyalin halaman dalam Word sangat bermanfaat: Apabila anda mempunyai dokumen dengan susun atur atau format tertentu yang anda ingin salin. Tidak seperti mencipta semula keseluruhan halaman dari awal

Lumpuhkan atau dayakan pemilihan salinan automatik untuk penyalinan dalam Terminal Lumpuhkan atau dayakan pemilihan salinan automatik untuk penyalinan dalam Terminal Mar 24, 2024 am 09:46 AM

Artikel ini akan menunjukkan kepada anda cara untuk mendayakan atau melumpuhkan penyalinan automatik pilihan ke papan keratan dalam Terminal Windows. Windows Terminal ialah emulator terminal berbilang tab yang dibangunkan oleh Microsoft khusus untuk Windows 11/10, menggantikan gesaan arahan tradisional. Ia menyokong aplikasi yang dijalankan seperti Command Prompt, PowerShell, WSL, Azure, dll. Selalunya apabila bekerja di terminal, pengguna perlu menyalin arahan dan output, namun terminal tidak menyokong operasi pemilihan penyalinan secara lalai. Teruskan membaca untuk mengetahui cara membetulkan isu ini. Bagaimana untuk mendayakan atau melumpuhkan penyalinan automatik pilihan ke cache dalam Terminal? Begini cara anda boleh mendayakan atau melumpuhkan penyalinan automatik pilihan ke papan keratan Terminal: Buka aplikasi Terminal dan klik di atas

Buka kunci sejarah papan keratan macOS, teknik salin dan tampal yang cekap Buka kunci sejarah papan keratan macOS, teknik salin dan tampal yang cekap Feb 19, 2024 pm 01:18 PM

Pada Mac, adalah perkara biasa untuk perlu menyalin dan menampal kandungan antara dokumen yang berbeza. Papan klip macOS hanya mengekalkan item yang terakhir disalin, yang mengehadkan kecekapan kerja kami. Nasib baik, terdapat beberapa aplikasi pihak ketiga yang boleh membantu kami melihat dan mengurus sejarah papan keratan kami dengan mudah. Cara Melihat Kandungan Papan Klip dalam Finder Terdapat pemapar papan keratan terbina dalam dalam Pencari, membolehkan anda melihat kandungan papan keratan semasa pada bila-bila masa untuk mengelakkan ralat menampal. Operasinya sangat mudah: buka Finder, klik menu Edit, dan kemudian pilih Tunjukkan Papan Klip. Walaupun fungsi melihat kandungan papan keratan dalam Finder adalah kecil, terdapat beberapa perkara yang perlu diberi perhatian: pemapar papan keratan dalam Finder hanya boleh memaparkan kandungan dan tidak boleh mengeditnya. Jika anda menyalin

Apakah kaedah tugasan dalam php? Apakah kaedah tugasan dalam php? Jul 26, 2023 pm 01:11 PM

Kaedah penetapan dalam PHP termasuk: 1. Penetapan langsung, gunakan operator "=" untuk menetapkan nilai secara langsung kepada pembolehubah 2. Penetapan rujukan, gunakan operator "=&" untuk memberikan rujukan kepada pembolehubah kepada pembolehubah lain; 3. Tugasan dinamik , gunakan pembolehubah pembolehubah untuk menetapkan nilai melalui bentuk rentetan nama pembolehubah; dan anda boleh menetapkan berbilang nilai pada satu nilai masa;

Ketahui definisi dan tugasan pembolehubah dalam Golang Ketahui definisi dan tugasan pembolehubah dalam Golang Jan 18, 2024 am 10:00 AM

Definisi dan penetapan pembolehubah di Golang memerlukan contoh kod khusus Di Golang, definisi dan penetapan pembolehubah adalah sangat mudah dan intuitif. Artikel ini akan memperkenalkan definisi dan penetapan pembolehubah dalam Golang melalui contoh kod tertentu. Mula-mula, mari kita lihat definisi pembolehubah di Golang. Di Golang, definisi pembolehubah boleh dilakukan menggunakan kata kunci var. Sintaks khusus adalah seperti berikut: jenis nama pembolehubah var Antaranya, var mewakili kata kunci definisi pembolehubah, dan nama pembolehubah ialah pembolehubah yang anda tentukan.

Petua dan Nota: Kaedah Tugasan Tatasusunan Rentetan yang berbeza Petua dan Nota: Kaedah Tugasan Tatasusunan Rentetan yang berbeza Dec 26, 2023 am 11:30 AM

Pengenalan kepada petua dan langkah berjaga-jaga untuk menggunakan cara yang berbeza untuk menetapkan nilai kepada tatasusunan rentetan: Dalam pengaturcaraan, selalunya perlu menggunakan tatasusunan untuk menyimpan satu set data yang berkaitan. Terutama apabila berurusan dengan rentetan, selalunya perlu menggunakan tatasusunan rentetan untuk menyimpan berbilang rentetan. Artikel ini akan memperkenalkan beberapa kaedah, petua dan langkah berjaga-jaga yang biasa untuk memberikan nilai kepada tatasusunan rentetan dan memberikan contoh kod. Tugasan langsung Tugasan langsung ialah cara paling mudah Anda boleh menetapkan nilai secara langsung kepada elemen tatasusunan semasa mengisytiharkan tatasusunan rentetan. Kod sampel adalah seperti berikut: Rentetan[]buah

Apakah kaedah untuk memberikan nilai kepada tatasusunan rentetan? Apakah kaedah untuk memberikan nilai kepada tatasusunan rentetan? Dec 25, 2023 pm 05:07 PM

Kaedah penugasan tatasusunan rentetan dalam bahasa pengaturcaraan biasa: 1. Python: "string_array = ["apple", "banana", "cherry"]" 2. Java: "String[] stringArray = {"apple", "banana " ", "ceri"}"; 3. C++ dan sebagainya.

See all articles