Что такое JS-эквивалент PHP $$ var? - PullRequest
0 голосов
/ 31 октября 2018

У меня есть форма с динамическими полями. Я хочу отформатировать сериализованные данные перед отправкой. Мне нужно воспроизвести PHP $$ var в Javascript.

Вот идея PHP:

У меня есть это:

$data = array('field1', 0, 'key');
$val = 'somevalue';

И я хочу это:

$field1[0]['key'] = 'somevalue';

Итак, вот как бы я поступил, если бы работал на PHP (я не уверен, что это сработает):

$data = array('field1', 0, 'key');
$val = 'somevalue';

$field1 = array();
$f = $data[0];           # 'field1'
$i = $data[1];           # 0
$k = $data[2];           # 'key'
$$f[$i][$k] = $val;      # $field1[0]['key'] = 'somevalue';

Я видел, что мы можем использовать window[var] в JS, но мне не удается заставить его работать, я попробовал это:

var val = 'somevalue';
var field1 = [];
var f = data[0];
var i = data[1];
var k = data[2];

window[f][i] = {};           # field1[0] must be an object
window[f][i][k] = val;       # field1[0] = {'key': 'somevalue'}

Как видите, не все так просто. Кроме того, этот код находится в пределах foreach, потому что у меня не только одно поле, но и много (field2, field3 ...).

В конце у меня есть что-то вроде:

var result = {
  field1: field1,
  field2: field2,
  ...
  field10: field10
}

// console.log(result);
{
  field1: [
    0 : Object { key: 'somevalue', key2: 'othervalue' }
    ...
    5 : Object { key: 'somevalue2', key2: 'othervalue2' }
  ]
  field2: [...]
  ...
}

EDIT:

Благодаря ответу @Nina Scholz:

function formatData(object, keys, value) {
    var last = keys.pop();

    keys.reduce((o, k, i, a) =>
        o[k] = o[k] || (isFinite(i + 1 in a ? a[i + 1] : last) ? [] : {}),
        object
    )[last] = value;

    return object;
}

var data = form.serializeArray();
var result = {};

$(data).each(function(i) {
    name = data[i].name;        // field name. Ex: "field1[0][key]"
    value = data[i].value;      // field value

    // Format: "field1[0][key]" => array("field1", "0", "key")
    array = name.split('[');
    array[1] = array[1].replace(']', '');
    array[2] = array[2].replace(']', '');

    // Format every array of data in a big object "result"
    formatData(result, array, value);
});

// JSON encoding of "result" in a hidden field for post-treatment
$('input[name=data]').val(JSON.stringify(result));

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Вы можете взять объект напрямую и указать путь к значению для установки. Этот подход проверяет ключ, если это число для массива в качестве значения по умолчанию. Если указан массив или объект, он не меняет структуру данных.

function setValue(object, keys, value) {
    var last = keys.pop();

    keys.reduce((o, k, i, a) =>
        o[k] = o[k] || (isFinite(i + 1 in a ? a[i + 1] : last) ? [] : {}),
        object
    )[last] = value;

    return object;
}

var val = 'somevalue',
    data = ['field1', 0, 'key'],
    result = {};

setValue(result, data, val);
console.log(result);
0 голосов
/ 31 октября 2018

Если у вас есть массив имен переменных, и вы хотите создать объект, ключи которого - это имена переменных, а значения - значения переменных, это пример того, как вы можете это сделать:

var fields = [ 'field1', 'field2', 'field3', 'field4'];

var field1 = 'foo';
var field2 = 'bar';
var field3 = 'baz';
var field4 = 'quux';

var obj = {};

for (var i = 0; i < fields.length; i++) {
    obj[fields[i]] = eval(fields[i]);
}

console.log(obj);

/*
{
  "field1": "foo",
  "field2": "bar",
  "field3": "baz",
  "field4": "quux"
}
*/
0 голосов
/ 31 октября 2018

Не следует создавать переменные динамически.

let o = {};
o[f][i][k] = val;

письмо o.field мало чем отличается от письма просто field

Чтобы ответить на ваш вопрос, вы не можете сделать это в javascript, как вы можете в php. Для справки, это считается плохим кодом и в PHP. В случае PHP он не позволяет компилятору применить все оптимизации.

Область действия функции отличается от глобальной области видимости.

Это записывает переменную bar в глобальной области, а не в локальной области

var bar = 123; // global bar

(() => {
    var bar; // local bar

    window["bar"] = 456; // this is writing in global "bar", not the local one
})();

console.log(bar);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...