2008-10-15 54 views
16

从Mozilla的JavaScript 1.7 changlog中可以看出,他们添加了解构赋值工具。可悲的是,我不是很喜欢的语法(为什么写a和b两次?):JavaScript中的解构赋值工作

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}这样的东西。但是,如果有人想要这种行为,那很容易做到。

什么是更好的解决方案?

回答

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功能变得更加广泛可用。

4

你不需要虚拟“_”变量。

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

这里有几个要点::您可以通过使用window对象范围直接创建“全局”变量

  • 我不会命名这个功能 “分配”,因为这是太普通 一个条件。
  • 要更接近类似于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 
+2

我同意的唯一的事情是,解构可能是一个更好的名字。 *来源,目的地是unix风格。 *填充全球范围是不好的。它不会导致组合性。 *将输出变量写入字符串会让您的编辑人员感到疲倦和困难。就像编写SQL一样。 – 2008-10-15 18:31:49

+0

@AndersRuneJensen由于这模仿了一个赋值,因此目标应该几乎肯定在左边 - 就像`[var1,var2] = arr`。而`destructure`是一个可怕的,无意露出的名字。我认为`assign`更好 - 毕竟,这被认为是一个通用的效用函数。如果不是,那么也许`massAssign`? – 2014-06-27 19:36:12

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

但是我认为以下的模式是更idomatic:

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/运行的代码)

1

这是我在PHPstorm 10那样:

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

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

- >单击应用。