16

从 JavaScript 1.7 的 Mozilla changlog 中可以看出,它们添加了解构赋值。可悲的是,我不太喜欢这种语法(为什么要写两次 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}。但是,如果有人想要这种行为,那很容易做到。

什么是更好的解决方案?

4

4 回答 4

23

首先,var [a, b] = f()在 JavaScript 1.7 中运行良好 - 试试吧!

其次,您可以使用以下方法稍微平滑使用语法with()

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

当然,这不允许您修改现有变量的值,因此恕我直言,它比 JavaScript 1.7 功能的用处要小得多。在我现在编写的代码,我只是直接返回对象并引用它们的成员——我将等待 1.7 的特性变得更广泛可用。

于 2008-10-15T21:25:39.557 回答
4

您不需要虚拟“_”变量。您可以使用窗口对象范围直接创建“全局”变量:

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

这里还有几点:

  • 我不会将这个函数命名为“assign”,因为这个术语太笼统了。
  • 为了更接近 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
于 2008-10-15T15:47:18.397 回答
1

这是我在 PHPstorm 10 中所做的:

文件 -> 设置 -> 语言和框架 -> ...

... 将 JavaScript 语言版本设置为例如 JavaScript 1.8.5...

-> 单击应用。

于 2015-12-22T19:19:23.973 回答
0

在标准 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/的代码)

于 2013-09-14T19:48:56.000 回答