【问题标题】:What is the JS equivalent of PHP $$var?PHP $$var 的 JS 等价物是什么?
【发布时间】:2019-04-04 19:54:34
【问题描述】:

我有一个带有动态字段的表单。我想在提交之前格式化一些序列化数据。我需要在 Javascript 中重现 PHP $$var。

这是 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';

我看到我们可以在 JS 中使用window[var],但我无法让它工作,我尝试了这个:

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: [...]
  ...
}

编辑:

感谢@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));

【问题讨论】:

  • 没有。但是您可以使用 eval,这是不可取的,也可以使用一个对象来收集所有想要的数据并通过密钥访问。
  • 也许添加表单(一个小表单)和你喜欢的序列化它更容易。
  • @NinaScholz data 已经是form.serializeArray() 的结果,我对其进行了 foreach 以格式化其中的一些数据。
  • @rpaskett 请在回答之前阅读我的整个帖子。我已经测试了你的解决方案。

标签: javascript php arrays variables


【解决方案1】:

如果你有一个变量名数组,并且你想创建一个对象,其中键是变量名,值是变量值,这是一个示例,说明如何做到这一点:

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"
}
*/

【讨论】:

    【解决方案2】:

    您不应该动态创建变量。

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

    o.field与写field没有太大区别

    要回答您的问题,您不能像在 php 中那样在 javascript 中执行此操作。作为记录,这在 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);
    

    【讨论】:

    • 我也试过eval(),但我没能成功,你能给我写一个与我前面的例子相对应的例子吗?
    • 对不起,这个答案是错误的。从 ES2015/ES6 开始,您可以使用变量作为对象字面量中的键。
    • 这与用户的要求有什么关系?函数范围不可访问,因为像 window 这样的变量是
    • 您不能创建具有动态名称的变量。唯一的方法是 eval eval("let " + name + " = " + whatever_serializer(value));
    【解决方案3】:

    您可以直接获取对象并获取设置值的路径。这种方法检查键,如果它是一个数组的数字作为默认值。如果给定一个数组或对象,它不会改变数据结构。

    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);

    【讨论】:

    • 哇,非常感谢@Nina!这正是我想做的,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2018-10-24
    • 2017-12-22
    • 2021-11-29
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多