简体   繁体   English

用JavaScript破坏分配

[英]Destructuring assignment in JavaScript

As can be seen in the Mozilla changlog for JavaScript 1.7 they have added destructuring assignment. 如在JavaScript 1.7的Mozilla changlog中所见,它们已添加了解构分配。 Sadly I'm not very fond of the syntax (why write a and b twice?): 可悲的是,我不太喜欢这种语法(为什么要两次写a和b?):

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

Something like this would have been a lot better: 这样的事情会好很多:

var [a, b] = f();

That would still be backwards compatible. 那仍然是向后兼容的。 Python-like destructuring would not be backwards compatible. 类似Python的解构将无法向后兼容。

Anyway the best solution for JavaScript 1.5 that I have been able to come up with is: 无论如何,我能够提出的JavaScript 1.5最佳解决方案是:

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

Which works like: 像这样工作:

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

But this really sucks because _ has no meaning. 但这确实很糟糕,因为_没有任何意义。 It's just an empty shell to store the names. 它只是一个空壳,用于存储名称。 But sadly it's needed because JavaScript doesn't have pointers. 但是可悲的是它是必需的,因为JavaScript没有指针。 On the plus side you can assign default values in the case the values are not matched. 在正方面,如果值不匹配,则可以分配默认值。 Also note that this solution doesn't try to slice the array. 另请注意,此解决方案不会尝试对数组进行切片。 So you can't do something like {first: 0, rest: 0} . 因此,您无法执行类似{first: 0, rest: 0} But that could easily be done, if one wanted that behavior. 但这很容易做到,只要有人愿意这样做。

What is a better solution? 有什么更好的解决方案?

First off, var [a, b] = f() works just fine in JavaScript 1.7 - try it! 首先, var [a, b] = f()在JavaScript 1.7中可以正常工作-试试吧!

Second, you can smooth out the usage syntax slightly using with() : 其次,您可以使用with() 稍微简化使用语法:

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

Of course, this won't allow you to modify the values of existing variables, so IMHO it's a whole lot less useful than the JavaScript 1.7 feature. 当然,这不允许您修改现有变量的值,因此恕我直言,它比JavaScript 1.7功能要有用得多。 In code I'm writing now , I just return objects directly and reference their members - I'll wait for the 1.7 features to become more widely available. 在代码我现在正在写,我只是直接返回对象,并引用其成员-我会等待1.7功能越来越广泛。

You don't need the dummy "_" variable. 您不需要虚拟的“ _”变量。 You can directly create "global" variables by using the window object scope: 您可以使用window对象范围直接创建“全局”变量:

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

Here are few more points: 这里还有几点:

  • I wouldn't name this function "assign" because that's too generic a term. 我不会将此函数命名为“ assign”,因为这是一个笼统的术语。
  • To more closely resemble JS 1.7 syntax, I'd make the function take the destination as the first argument and the source as the second argument. 为了更类似于JS 1.7语法,我将使函数将目标作为第一个参数,将源作为第二个参数。
  • Using an object literal to pass the destination variables is cool but can be confused with JS 1.7 destructuring where the destination is actually an object and not an array. 使用对象文字传递目标变量很酷,但是可以与JS 1.7解构混淆,后者的目标实际上是一个对象而不是数组。 I prefer just using a comma delimited list of variable names as a string. 我更喜欢只使用逗号分隔的变量名列表作为字符串。

Here's what I came up with: 这是我想出的:

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

Here's what I did in PHPstorm 10: 这是我在PHPstorm 10中所做的事情:

File -> Settings -> Languages & Frameworks -> ... 文件->设置->语言和框架-> ...

... set JavaScript language version to eg JavaScript 1.8.5... ...将JavaScript语言版本设置为例如JavaScript 1.8.5 ...

-> click Apply. ->单击“应用”。

In standard JavaScript we get used to all kinds of ugliness, and emulating destructuring assignment using an intermediate variable is not too bad: 在标准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 );

However I think the following pattern is more 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 );
});

Note, that instead of returning the two results as an array, we pass them as arguments to a callback function. 请注意,我们将两个结果作为参数传递给回调函数,而不是将两个结果作为数组返回。

(See code running at http://jsfiddle.net/vVQE3/ ) (请参阅在http://jsfiddle.net/vVQE3/上运行的代码)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM