Apakah tugasan yang memusnahkan?
Penugasan penstrukturan membolehkan anda menetapkan nilai harta tatasusunan dan objek kepada siri pembolehubah menggunakan sintaks yang serupa dengan tatasusunan atau literal objek. Sintaks ini sangat ringkas dan lebih jelas daripada akses harta tradisional.
Akses tiga item pertama tatasusunan tanpa menggunakan tugasan memusnahkan:
var first = someArray[0]; var second = someArray[1]; var third = someArray[2]; var first = someArray[0]; var second = someArray[1]; var third = someArray[2];
Selepas menggunakan tugasan yang memusnahkan, kod yang sepadan menjadi lebih ringkas dan boleh dibaca:
var [first, second, third] = someArray; var [first, second, third] = someArray;
SpiderMonkey (enjin JavaScript Firefox) sudah menyokong kebanyakan ciri tugasan yang memusnahkan, tetapi tidak sepenuhnya.
Memusnahkan tugasan tatasusunan dan objek boleh lelar
Kami telah melihat contoh tugasan pemusnahan tatasusunan di atas Bentuk umum sintaks ini ialah:
[ variable1, variable2, ..., variableN ] = array; [ variable1, variable2, ..., variableN ] = array;
Ini akan menetapkan item yang sepadan dalam tatasusunan kepada pembolehubah1 kepada pembolehubahN dalam urutan Jika anda perlu mengisytiharkan pembolehubah pada masa yang sama, anda boleh menambah kata kunci var, let atau const di hadapan ungkapan yang memusnahkan.
var [ variable1, variable2, ..., variableN ] = array; let [ variable1, variable2, ..., variableN ] = array; const [ variable1, variable2, ..., variableN ] = array; var [ variable1, variable2, ..., variableN ] = array; let [ variable1, variable2, ..., variableN ] = array; const [ variable1, variable2, ..., variableN ] = array;
Malah, anda boleh bersarang pada sebarang kedalaman:
var [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); // 1 console.log(bar); // 2 console.log(baz); // 3 var [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); // 1 console.log(bar); // 2 console.log(baz); // 3
Selain itu, adalah mungkin untuk melangkau item tertentu dalam tatasusunan:
var [,,third] = ["foo", "bar", "baz"]; console.log(third); // "baz" var [,,third] = ["foo", "bar", "baz"]; console.log(third); // "baz"
Anda juga boleh menggunakan ungkapan Rehat untuk menangkap item yang tinggal dalam tatasusunan:
var [head, ...tail] = [1, 2, 3, 4]; console.log(tail); // [2, 3, 4] var [head, ...tail] = [1, 2, 3, 4]; console.log(tail); // [2, 3, 4]
Jika tatasusunan keluar dari sempadan atau mengakses item yang tidak wujud dalam tatasusunan, anda akan mendapat nilai yang sama seperti mengakses melalui indeks tatasusunan: undefined.
console.log([][0]); // undefined var [missing] = []; console.log(missing); // undefined console.log([][0]); // undefined var [missing] = []; console.log(missing); // undefined
Perhatikan bahawa kaedah pemusnahan dan penetapan tatasusunan juga digunakan untuk objek boleh dilalui:
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(); console.log(sixth); // 5 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(); console.log(sixth); // 5
Memusnahkan tugasan objek
Tugasan pemusnahan objek membolehkan anda mengikat pembolehubah kepada nilai sifat objek yang berbeza. Nyatakan nama harta yang akan diikat, diikuti dengan pembolehubah yang akan diikat:
var robotA = { name: "Bender" }; var robotB = { name: "Flexo" }; var { name: nameA } = robotA; var { name: nameB } = robotB; console.log(nameA); // "Bender" console.log(nameB); // "Flexo" var robotA = { name: "Bender" }; var robotB = { name: "Flexo" }; var { name: nameA } = robotA; var { name: nameB } = robotB; console.log(nameA); // "Bender" console.log(nameB); // "Flexo"
Apabila nama atribut terikat adalah sama dengan nama pembolehubah yang menerima nilai atribut, terdapat satu lagi gula sintaksis:
var { foo, bar } = { foo: "lorem", bar: "ipsum" }; console.log(foo); // "lorem" console.log(bar); // "ipsum" var { foo, bar } = { foo: "lorem", bar: "ipsum" }; console.log(foo); // "lorem" console.log(bar); // "ipsum"
Seperti tatasusunan, ia juga boleh disarangkan:
var complicatedObj = { arrayProp: [ "Zapp", { second: "Brannigan" } ] }; var { arrayProp: [first, { second }] } = complicatedObj; console.log(first); // "Zapp" console.log(second); // "Brannigan" var complicatedObj = { arrayProp: [ "Zapp", { second: "Brannigan" } ] }; var { arrayProp: [first, { second }] } = complicatedObj; console.log(first); // "Zapp" console.log(second); // "Brannigan"
Apabila memusnahkan harta yang tidak wujud, anda akan mendapat tidak ditentukan:
var { missing } = {}; console.log(missing); // undefined var { missing } = {}; console.log(missing); // undefined
Terdapat satu lagi perangkap yang berpotensi apabila menggunakan tugasan memusnahkan objek, tiada pengisytiharan berubah (tiada kata kunci var, let atau const) semasa tugasan memusnahkan:
{ blowUp } = { blowUp: 10 }; // Syntax error { blowUp } = { blowUp: 10 }; // Syntax error
Ini kerana sintaks JavaScript memberitahu enjin bahawa mana-mana pernyataan yang bermula dengan { ialah blok pernyataan (contohnya, {console} ialah blok pernyataan undang-undang Penyelesaiannya adalah untuk membalut keseluruhan pernyataan dengan sepasang kurungan:
({ safe } = {}); // No errors ({ safe } = {}); // No errors
Situasi lain
Apabila anda cuba memusnahkan null atau undefined, anda akan mendapat ralat jenis:
var {blowUp} = null; // TypeError: null has no properties var {blowUp} = null; // TypeError: null has no properties
Walau bagaimanapun, anda boleh memusnahkan jenis asas lain (Boolean, String dan Number) dan anda akan mendapat undefined:
var {wtf} = NaN; console.log(wtf); // undefined var {wtf} = NaN; console.log(wtf); // undefined
Hasilnya mungkin mengejutkan anda, tetapi jika anda melihat lebih dalam, sebabnya sebenarnya sangat mudah. Apabila melakukan pemusnahan dan penetapan objek, objek yang dimusnahkan akan dipaksa menjadi Objek Kecuali untuk null dan undefined, jenis lain boleh dipaksa menjadi objek. Apabila melakukan penetapan struktur tatasusunan, objek yang dimusnahkan dikehendaki mempunyai penyeberang.
Nilai lalai
Anda boleh menentukan nilai lalai untuk sifat yang tidak wujud:
var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3 var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3
Aplikasi Praktikal
Parameter fungsi
Sebagai pembangun, kami sering menggunakan objek yang mengandungi berbilang sifat sebagai parameter fungsi untuk melaksanakan API yang lebih fleksibel, dan bukannya meminta pengguna API mengingati beberapa parameter dalam susunan tertentu. Kita boleh menggunakan tugasan memusnahkan objek untuk mengelakkan akses atribut setiap kali parameter digunakan:
function removeBreakpoint({ url, line, column }) { // ... } function removeBreakpoint({ url, line, column }) { // ... }
Objek konfigurasi
Untuk menambah baik contoh di atas, kami boleh menyediakan nilai lalai untuk sifat objek yang akan dimusnahkan Ini sangat praktikal untuk objek yang digunakan sebagai parameter konfigurasi, kerana banyak item konfigurasi mempunyai nilai lalai yang munasabah. Sebagai contoh, parameter kedua kaedah ajax jQuery ialah objek konfigurasi, yang boleh kita laksanakan seperti ini:
jQuery.ajax = function (url, { async = true, beforeSend = noop, cache = true, complete = noop, crossDomain = false, global = true, // ... more config }) { // ... do stuff }; jQuery.ajax = function (url, { async = true, beforeSend = noop, cache = true, complete = noop, crossDomain = false, global = true, // ... more config }) { // ... do stuff };
Ini mengelakkan pertindihan kod seperti ini: var foo = config.foo || theDefaultFoo;.
Digunakan dengan iterator
Apabila melintasi objek Peta, kita boleh menggunakan tugasan memusnahkan untuk melintasi [kunci, nilai]:
var map = new Map(); map.set(window, "the global"); map.set(document, "the document"); for (var [key, value] of map) { console.log(key + " is " + value); } // "[object Window] is the global" // "[object HTMLDocument] is the document" var map = new Map(); map.set(window, "the global"); map.set(document, "the document"); for (var [key, value] of map) { console.log(key + " is " + value); } // "[object Window] is the global" // "[object HTMLDocument] is the document"
Kunci traverse sahaja:
for (var [key] of map) { // ... } for (var [key] of map) { // ... } 只遍历值: for (var [,value] of map) { // ... } for (var [,value] of map) { // ... }
Kembalikan berbilang nilai
Mengembalikan tatasusunan dan mengekstrak nilai pulangan melalui tugasan yang memusnahkan:
function returnMultipleValues() { return [1, 2]; } var [foo, bar] = returnMultipleValues(); function returnMultipleValues() { return [1, 2]; } var [foo, bar] = returnMultipleValues();
Atau, kembalikan objek pasangan nilai kunci:
function returnMultipleValues() { return { foo: 1, bar: 2 }; } var { foo, bar } = returnMultipleValues(); function returnMultipleValues() { return { foo: 1, bar: 2 }; } var { foo, bar } = returnMultipleValues();
Kedua-dua ini lebih baik daripada menggunakan pembolehubah perantaraan:
function returnMultipleValues() { return { foo: 1, bar: 2 }; } var temp = returnMultipleValues(); var foo = temp.foo; var bar = temp.bar; function returnMultipleValues() { return { foo: 1, bar: 2 }; } var temp = returnMultipleValues(); var foo = temp.foo; var bar = temp.bar;
Gunakan borang sambungan:
function returnMultipleValues(k) { k(1, 2); } returnMultipleValues((foo, bar) => ...); function returnMultipleValues(k) { k(1, 2); } returnMultipleValues((foo, bar) => ...);
导入 CommonJS 模块的指定部分
还没使用过 ES6 的模块吧,那至少使用过 CommonJS 吧。当导入一个 CommonJS 模块 X 时,模块提供的方法也许多余你实际使用的。使用解构赋值,你可以明确指定你需要使用模块的哪些部分:
const { SourceMapConsumer, SourceNode } = require("source-map"); const { SourceMapConsumer, SourceNode } = require("source-map");
如果你使用 ES6 的模块机制,你可以看到 import 声明时有一个类似的语法。
结论
我们看到,解构赋值在很多场景下都很实用。在 Mozilla,我们已经有很多经验。Lars Hansen 在 10 年前就向 Opera 引入了解构赋值,Brendan Eich 在稍微晚点也给 Firefox 添加了支持,最早出现在 Firefox 2 中。因此,解构赋值已经渗透到我们每天对 JS 的使用中,悄悄地使我们的代码更简短、整洁。