Глубокое понимание деструктурирующего присвоения массивов и объектов.

JavaScript

es6提供了一个非常好的特性,即变量的解构赋值。从而我们可以方便的从数组和对象中提取数据并将它们赋值给变量。这是非常必要的。先来看在这个新特性发布之前我们是如何从数组中提取数据的。 следующим образом:

let nums = [1,2,3,4,5];
let num1 = nums[0];
let num2 = nums[1];

console.log(num1); // logs 1
console.log(num2); // logs 2

для отnumsДанные извлекаются из массива, и мы многократно повторяем один и тот же код. Назначение деструктурирования ES6 сделает это очень простым и понятным.

Назначение деструктурирования массива

Получить значения из массива и присвоить значения переменным по соответствующим позициям. следующим образом:

 let [num1,num2,num3] = [1,2,3];
 console.log({num1},{num2},{num3})

задание "сопоставление с образцом"

Это «сопоставление с образцом», поскольку образец с обеих сторон знака равенства одинаков, переменной слева будет присвоено соответствующее значение.

let [num_s,nums,num_e] = [1,[2,3,4],5];
console.log(num_s) // logs 1
console.log(nums) // logs [2,3,4]
console.log(num_e) // logs 5

пропускать элементы с запятыми

let [num1,,,num4] = [1,2,3,4];
console.log(num1) // logs 1
console.log(num4) // logs 4

let [,num2,,num4] = [1,2,3,4];
console.log(num2) // logs 2
console.log(num4) // logs 4

Посмотрите на массив слева от присваивания переменной. Обратите внимание, что здесь не одна запятая, а три. Разделитель-запятая используется для пропуска значений в массиве. Поэтому, если вы хотите пропустить элемент в массиве, просто используйте запятую.

присвоение остальной части массива

Что, если мы хотим присвоить некоторые элементы массива переменной, а остальные элементы массива сохранить как массив и присвоить его указанной переменной? В этом случае мы можем сделать:

let [num1,...nums] = [1,2,3,4];
console.log(num1) // logs 1
console.log(nums) // logs [2,3,4]

Используя этот метод, вы можете легко присвоить оставшиеся элементы указанной переменной.

Деструктуризация не удалась, присвоениеundefined

let [num1] = [];
let [num2, num3] = [1];
console.log(num1) // logs undefined
console.log(num3) // logs undefined

Переменные кодаnum1с переменнойnum3Согласно принципу сопоставления с образцом, нет соответствующего значения для сопоставления, поэтому он возвращаетundefined. в то время как переменнаяnum2В соответствии с принципом сопоставления с образцом ему присваивается значение 2.

Деструктивное назначение функций

Присваивание деструктурирования также может извлекать данные из массива, возвращаемого функцией. Предположим, у нас есть функция, которая возвращает массив, как в следующем примере:

function getLists() {
    let lists = [1,2,3,4,5]
    return lists;
}
let [num1,...nums] = getLists();

console.log(num1); // logs 1
console.log(nums); // logs [2,3,4,5]

использовать по умолчанию

Назначение деструктурирования массива может установить значения по умолчанию для переменных в случае, если значение, извлеченное из массива,undefined(для предотвращения деструктивных сбоев)

let [name = "暂无姓名",sex = "女"] = ["April"];

console.log(name); // "April"
console.log(sex); // "女"

переменные в кодеnameЗначение по умолчанию"暂无姓名"Но по принципу сопоставления левого и правого шаблона,nameназначается как"April", потому что переменнаяsexЗначение не совпало, поэтому его значение по-прежнему остается значением по умолчанию."女".

Примечание 1: ES6 внутренне использует оператор строгого равенства (===), чтобы определить, имеет ли местоположение значение. Таким образом, только если член массива строго равенundefined, вступит в силу значение по умолчанию.

let [num1 = 1] = [undefined];
console.log(num1) // logs 1

let [num2 = 2] = [null];
console.log(num2) // logs null

В коде, потому чтоnullстрого не равноundefined, значение по умолчанию не вступит в силу. Следовательно, выводnull

Заметка 2: Если значением по умолчанию является функция, функция будет очень ленивой, то есть функция будет выполняться только тогда, когда она используется.

 function getLists(){
    let lists = [1,2,3,4,5]
    return lists; 
 }
let [lists = getLists()] = [1];
console.log(lists) // logs 1
// 因为变量 lists 可以匹配到值,所以函数 getLists() 并不会执行。

 function getLists(){
    let lists = [1,2,3,4,5]
    return lists; 
 }
let [lists = getLists()] = [];
console.log(lists) // logs [1,2,3,4,5]
// 因为变量 lists 无法匹配到值,函数 getLists() 就会执行。故而返回数据 [1,2,3,4,5]

Заметка 3: значения по умолчанию могут ссылаться на другие переменные, присвоенные деструктуризацией, но переменная уже должна быть объявлена.

let [x = 1, y = x] = [];     // logs x=1; y=1
let [x = 1, y = x] = [2];    // logs x=2; y=2
let [x = 1, y = x] = [1, 2]; // logs x=1; y=2
let [x = y, y = 1] = [];     //logs 这就要报错啦,因为x用y做默认值时,y还没有声明。

Переменные обмена

let num1 = 1;
let num2 = 2;

[num1,num2] = [num2,num1];

console.log({num1}); // logs 2
console.log({num2}); // logs 1

Назначение деструктуризации объекта

Зачем использовать присваивание деструктуризации объекта? ?

 let profiles = {
    name:'April',
    nickname:"二十七刻",
    sign:"不以物喜,不以己悲。"
 }
           
let name = profiles.name;
let nickname = profiles.nickname;
let sign = profiles.sign;

console.log({name}) // "April"
console.log({nickname})// "二十七刻"
console.log({sign}) // "不以物喜,不以己悲。"

Предположим, мы хотим получить объект изprofilesПолучите данные и назначьте их новой переменной. Вы должны продолжать повторять значение и назначение. Код многословен и неудобен в сопровождении. При деструктурирующем назначении объектов этой проблемы не существует.

Назначение с тем же именем свойства

Переменная назначения деструктурирования объекта должна иметь то же имя, что и свойство, чтобы получить правильное значение. следующим образом:

let profiles = {
     name:'April', 
     nickname:"二十七刻", 
     sign:"不以物喜,不以己悲。"
}
let {name,nickname,sign} = profiles;

console.log({name})    // logs "April"
console.log({nickname})// logs "二十七刻"
console.log({sign})    // logs "不以物喜,不以己悲。"

Деструктуризация не удалась, присвоениеundefined

let profiles = {
    name:'April',
    nickname:"二十七刻",
    sign:"不以物喜,不以己悲。"
}
let {name,sex} = profiles;

console.log(name) // logs "April"
console.log(sex) // logs undefined

В приведенном выше коде, потому чтоprofilesобъект неsexсвойства, поэтому переменныеsexЧтобы получить какое-либо значение, так что назначениеundefined.

объявить переменную перед присваиванием

В присваивании деструктурирования объекта переменные могут быть объявлены до присваивания. следующим образом:

let profiles = {
    name:'April',
    nickname:"二十七刻",
    sign:"不以物喜,不以己悲。"
}
let name,nickname,sign;
{name,nickname,sign} = profiles;

console.log(name) // logs Error : "Unexpected token ="

嘿呀~报错了! Почему? ? ?

Причина: потому что забыл{}внешняя запись().

Примечание 1()оператор присваивания.因为 JavaScript 引擎会将{name,nickname,sign}Читать как блок кода, а не литерал объекта.

Заметка 2: при использовании этого синтаксиса предыдущая строка кода должна начинаться с;конец, в противном случае он будет рассматриваться как функция и выполнить код на предыдущей строке.

это странный синтаксис :({} = '');

Правильный способ следующий:

let profiles = {
    name:'April',
    nickname:"二十七刻",
    sign:"不以物喜,不以己悲。"
}
let name,nickname,sign;
({name,nickname,sign} = profiles);

console.log({name},{nickname},{sign})
// logs {name: "April"} {nickname: "二十七刻"} {sign: "不以物喜,不以己悲。"}

использовать новое имя переменной

Что, если мы захотим заменить имена свойств объекта новыми именами переменных? код показывает, как показано ниже:

let profiles = {
    name:"April",
    age:"27"
}
let {name:userName,age:userAge} = profiles;

console.log(userName) // logs "April"
console.log(userAge) // logs "27"

Из этого видно, что деструктурирующее присваивание объекта на самом делеlet {name:name,age:age} = {name:"April",age:"27"}Сокращение для кода. То есть внутренний механизм присваивания деструктуризации объекта заключается в том, чтобы сначала найти свойство с таким же именем, а затем присвоить его соответствующей переменной. На самом деле назначено последнее, а не первое.

В приведенном выше кодеnameСопоставление картины,userNameявляется переменной. На самом деле присваивается переменнаяuserName, а не узорname.

использовать по умолчанию

undefinedundefined.

let staff = {name: "April", country: "China", job: "Developer"};
let {name = "暂无姓名", age = "暂无年龄"} = staff;

console.log({name}); // logs "April"
console.log({age}); // logs "暂无年龄"

переменные в кодеnameЗначение по умолчанию — «пока нет имени», но объектstaffnameполе, поэтому оно назначаетсяApril, а объектstaffне вageТаким образом, этому свойству присваивается значение «нет возраста» и оно принимает собственное значение по умолчанию.

Имя вычисляемого свойства

Расчетное имя атрибута - это еще один объект объекта, но и для деконструкции задания объекта. Вы можете указать имя выражения свойства, поставить его[], следующим образом:

let staff = {name: "April", country: "China", job: "Developer"};
let prop = "name";
let {[prop]: name} = staff;

console.log({name}); // logs "April"

присвоение остальной части объекта

Операции деструктурирования также можно применять к назначениям деструктурирования для получения пар ключ-значение, которые не были назначены, и эти пары ключ-значение помещаются в новый объект. следующим образом:

let staff = {name: "April", country: "China", job: "Developer",nickname:"二十七刻"};
let {country,...infos} = staff;

console.log(country) //logs "China"
console.log(infos) // logs {name: "April", job: "Developer", nickname: "二十七刻"}

Разрушение присвоения вложенных объектов

let staffs = {
    group1:[ { id:"007", name:"April"}]
}
let {group1,group1:[{id,name}]} = staffs;

console.log(group1) // logs [{ id:"007", name:"April"}]
console.log(id) // logs "007"
console.log(name) // logs "April"

Обратите внимание, что в кодеgroup1是模式,不是变量。 Если вы хотитеgroup1

наконец