Деструктуризация присваивания в JavaScript

Как видно из журнала изменений Mozilla для JavaScript 1.7, они добавили назначение деструктуризации. К сожалению, мне не очень нравится синтаксис (зачем писать a и b дважды?):

var a, b;  
[a, b] = f();

Что-то вроде этого было бы намного лучше:

var [a, b] = f();

Это все равно будет обратно совместимо. Деструктуризация, подобная Python, не будет обратно совместимой.

В любом случае лучшее решение для JavaScript 1.5, которое мне удалось придумать, это:

function assign(array, map) {
    var o = Object();
    var i = 0;
    $.each(map, function(e, _) {
        o[e] = array[i++];
    });
    return o;
}

Что работает как:

var array = [1,2];
var _ = assign[array, { var1: null, var2: null });
_.var1; // prints 1
_.var2; // prints 2

Но это действительно отстой, потому что _ не имеет значения. Это просто пустая оболочка для хранения имен. Но, к сожалению, это необходимо, потому что в JavaScript нет указателей. С другой стороны, вы можете назначить значения по умолчанию в случае, если значения не совпадают. Также обратите внимание, что это решение не пытается разрезать массив. Значит, нельзя сделать что-то вроде {first: 0, rest: 0}. Но это можно было легко сделать, если бы кто-то захотел такого поведения.

Какое решение лучше?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
16
0
10 411
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вам не нужна фиктивная переменная "_". Вы можете напрямую создавать «глобальные» переменные, используя область объекта окна:

window["foo"] = "bar";
alert(foo); // Gives "bar"

Вот еще несколько моментов:

  • Я бы не назвал эту функцию "назначить", потому что это слишком общий термин.
  • Чтобы больше походить на JS 1.7, я бы сделал так, чтобы функция принимала пункт назначения в качестве первого аргумент и источник как Второй аргумент.
  • Использование литерала объекта для передачи целевых переменных - это круто, но его можно спутать с деструктуризацией JS 1.7, где адресатом на самом деле является объект, а не массив. Я предпочитаю просто использовать список имен переменных, разделенных запятыми, в виде строки.

Вот что я придумал:

function destructure(dest, src) {  
    dest = dest.split(",");  

    for (var i = 0; i < src.length; i++) {  
        window[dest[i]] = src[i];  
    }  
}  

var arr = [42, 66];  

destructure("var1,var2", arr); 

alert(var1); // Gives 42
alert(var2); // Gives 66

Единственное, с чем я согласен, это то, что лучше назвать деструктуризацию. * источник, назначение - стиль unix. * заполнение глобальной области видимости не очень хорошо. Это не приводит к компоновке. * Запись выходных переменных в виде строки утомляет и труднее проверять редактору. Как писать SQL.

Anders Rune Jensen 15.10.2008 22:31

@AndersRuneJensen Поскольку это имитирует назначение, пункт назначения почти наверняка должен быть слева - таким образом он выглядит как [var1, var2] = arr. А destructure - ужасное имя, не раскрывающее никаких намерений. Я думаю, что assign лучше - в конце концов, это предполагаемый, чтобы быть универсальной функцией полезности. Если нет, то может massAssign?

Marnen Laibow-Koser 27.06.2014 23:36
Ответ принят как подходящий

Во-первых, var [a, b] = f() отлично работает в JavaScript 1.7 - попробуйте!

Во-вторых, вы можете сгладить синтаксис использования немного с помощью with():

var array = [1,2];
with (assign(array, { var1: null, var2: null }))
{
   var1; // == 1
   var2; // == 2
}

Конечно, это не позволит вам изменять значения существующих переменных, поэтому, IMHO, это намного менее полезно, чем функция JavaScript 1.7. В коде я пишу Теперь, я просто возвращаю объекты напрямую и ссылаюсь на их элементы - я буду ждать, пока функции 1.7 станут более доступными.

На сегодняшний день var [a,b] = [1,2]; вызывает синтаксическую ошибку в Chrome.

Marcin 06.04.2012 20:24

@Marcin: JavaScript 1.7 - это Только язык Mozilla.

Shog9 06.04.2012 21:25

Обратите внимание, что with может быть опасным, поскольку Собственная документация Mozilla заявляет: «Использование with не рекомендуется и запрещено в строгом режиме ECMAScript 5. Рекомендуемая альтернатива - назначить объект, свойства которого вы хотите получить доступ к временной переменной».

Michael Mior 10.04.2013 17:59

Это то, что делает OP, @Michael

Shog9 10.04.2013 20:44

@ Shog9 Действительно, это так. Я хотел сказать, что в этом нет ничего плохого и что альтернатива с использованием with имеет серьезные недостатки.

Michael Mior 13.04.2013 05:33

Будет доступно в ECMAScript 6 примерно в середине 2015 г., см. en.wikipedia.org/wiki/ECMAScript

pkopac 25.02.2015 17:26

with также запрещен в строгом режиме, который является режимом действительно полезно для включения ...

T.J. Crowder 20.04.2015 17:31

На сегодняшний день var [a,b] = [1,2] работает в Chrome, Firefox, Edge и Node.

Chris 30.09.2016 04:17

В стандартном JavaScript мы привыкли ко всем видам уродства, и эмуляция деструктурирующего присваивания с использованием промежуточной переменной не так уж и плоха:

function divMod1(a, b) {
    return [ Math.floor(a / b), a % b ];
}

var _ = divMod1(11, 3);
var div = _[0];
var mod = _[1];
alert("(1) div = " + div + ", mod = " + mod );

Однако я думаю, что следующая закономерность более идеоматична:

function divMod2(a, b, callback) {
    callback(Math.floor(a / b), a % b);
}

divMod2(11, 3, function(div, mod) {
    alert("(2) div = " + div + ", mod = " + mod );
});

Обратите внимание, что вместо того, чтобы возвращать два результата в виде массива, мы передаем их в качестве аргументов функции обратного вызова.

(См. Код, работающий на http://jsfiddle.net/vVQE3/)

Вот что я сделал в PHPstorm 10:

Файл -> Настройки -> Языки и рамки -> ...

... установите версию языка JavaScript, например, JavaScript 1.8.5 ...

-> щелкните Применить.

Другие вопросы по теме