JavaScript中类似于PHP的list()函数的等效方法

71

真的很喜欢那个函数。

$matches = array('12', 'watt');
list($value, $unit) = $matches;

有没有 JavaScript 的相对应方法?


7
好的,那就翻译为:“嗯,这不太简洁,是吧?” - Kzqai
2
我从未觉得list()有用,上面的代码对我来说只是在喊对象:var power = { 'unit': 'watt', 'amount': 12 } - Gordon
5
很丑并且很长。我认为使用“list()”可以使代码更易读。 - Markus Hedlund
@Tchalvak 添加外部依赖库从来都不是更加简洁的方式。 - ZJR
3
PHP的list()非常方便,如果你想要交换变量值而不需要使用临时变量:list($b, $a) = array($a, $b); - Avatar
显示剩余7条评论
9个回答

62

在“较新”的JavaScript版本中,存在解构赋值-Javascript 1.7。它可能仅受到基于Mozilla的浏览器的支持,也可能在Rhino中支持。

var a = 1;  
var b = 3;  

[a, b] = [b, a];  

编辑:实际上,如果V8 JavaScript库(因此Chrome)支持此功能,我不会感到惊讶。但也不要期望它。 现在在所有现代浏览器中支持(当然,IE除外)。


6
好的!我真的很喜欢新版JavaScript中加入的所有酷炫功能!只是感觉我们可能要等很久才能开始使用它们。 - Markus Hedlund
1
2015年,仍未得到V8的支持。 - user1598585
1
自2006年起,Firefox就支持它。但到了2015年,V8/Chrome仍未支持。Chrome是新的IE。 - cronvel
在2018年使用它时要小心; IE从未支持过它,而且许多人仍在使用它。用于判断兼容性:http://kangax.github.io/compat-table/es6/ - Autumn Leonard
来自2019年3月的报告。这在Chrome 72(64位)中运行。 - akinuri

20

试试这个:

matches = ['12', 'watt'];
[value, unit] = matches; 

19

现在ES6直接支持这一点,通过数组解构


const matches = ['12', 'watt'];
const [value, unit] = matches;

2
截至2019年中期,这是最佳答案。许多代码检查工具会在接受的答案中抛出“[variable]未定义(no-undef)”警告。这个解决了这个问题。请注意,在for...of循环中也可以进行数组解构。 - Tyler V.

4
这是我在Javascript中使用List/Explode的解决方案。 Fiddle Working Example 首先是实现:
var dateMonth = "04/15";
dateMonth.split("/").list("month","day", "year");
month == "04";
day == "15";
year == null;

它还允许限定新生成的变量的范围:
var scoped = (function()
{ 
    var dateMonth = "07/24/2013"; 
    dateMonth.split("/").list("month","day", "year", this);
    this.month == "07";
    this.day == "24";
    this.year == "2013";
})();

这是通过修改数组原型实现的。
Array.prototype.list = function()
{
    var 
        limit = this.length,
        orphans = arguments.length - limit,
        scope = orphans > 0  && typeof(arguments[arguments.length-1]) != "string" ? arguments[arguments.length-1] : window 
    ;

    while(limit--) scope[arguments[limit]] = this[limit];

    if(scope != window) orphans--;

    if(orphans > 0)
    {
        orphans += this.length;
        while(orphans-- > this.length) scope[arguments[orphans]] = null;  
    }  
}

我坚持使用我的解决方案。如果你尝试像这样的东西:matches = ['12', 'watt']; [value, unit] = matches; 或者 function () { var [year, month] = $(this).val().split("/");在Chrome中,它会抛出一个错误: "ReferenceError: Invalid left-hand side in assignment" - lac_dev
window作为默认对象使用是一个非常糟糕的想法。 - Bergi
@Bergi 他只是使用默认参数。你可以在最后一个参数提供一个对象,它会使用那个对象。 - micahblu
@lac_dev 我很喜欢这个小脚本,它对我非常有效。很好的是你考虑到了超出数据范围的标签。 - micahblu

2

CoffeeScript提供了使用以下语法的解构赋值:

[a, b] = someFunctionReturningAnArray()

这与最新JavaScript版本提供的功能几乎完全相同。然而,CoffeeScript生成的编译JS甚至与IE6的JavaScript引擎兼容,因此如果兼容性至关重要,则它是一个很好的选择。


2

这篇帖子中的第二个链接已经失效(404-这不是您要查找的网页)。 - Pang

1

由于大多数JavaScript实现尚不支持该功能,您可以以更类似于JavaScript的方式执行它:

function list(){
    var args = arguments;
    return function(array){
        var obj = {};
        for(i=0; i<args.length; i++){
            obj[args[i]] = array[i];
        }
        return obj;
    };
}

例子:

var array = ['GET', '/users', 'UserController'];
var obj = {};

obj = list('method', 'route', 'controller')(array);

console.log(obj.method);        // "GET"
console.log(obj.route);         // "/users"
console.log(obj.controller);    // "UserController"

查看 jsFiddle


另一种方法是向Array.prototype添加一个列表方法(即使我不建议这样做):

Array.prototype.list = function(){
    var i, obj = {};
    for(i=0; i<arguments.length; i++){
        obj[arguments[i]] = this[i];
    }
    // if you do this, you pass to the dark side `,:,´
    this.props = obj;
    return obj;
};

例子:

/**
 * Example 1: use Array.prototype.props
 */

var array = ['GET', '/users', 'UserController'];
array.list('method', 'route', 'controller');

console.log(array.props.method);        // "GET"
console.log(array.props.route);         // "/users"
console.log(array.props.controller);    // "UserController"

/**
 * Example 2: use the return value
 */

var array = ['GET', '/users', 'UserController'];
var props = array.list('method', 'route', 'controller');

console.log(props.method);      // "GET"
console.log(props.route);       // "/users"
console.log(props.controller);  // "UserController"

查看这个fiddle


0
这是我的尝试;我尽可能地缩短了它,而不用编写一个函数来完成它。但是必须小心“this”的范围:
list = ["a","b","c"];
vals = [1,2,3];
for(var i in vals)this[list[i]]=vals[i];
console.log(a,b,c);

还不错,让人忍俊不禁。我仍然一次只分配一个变量:

a=vals[0];
b=vals[1];
c=vals[2];

这种方式要短得多。此外,如果你有一堆变量,它们应该放在数组中,甚至更好的做法是将它们作为闭包的属性,而不是分别声明它们。


-2
function list(fn,array){
    if(fn.length && array.length){
        for(var i=0;i<array.length;i++){
            var applyArray = [];
            for(var j=0;j<array[i].length;j++){
                fn[j] = array[i][j];
                applyArray.push(fn[j]);
            }
        fn.apply(this,applyArray);
       }
   }
}

例子:

//array array mixture for composure
var arrayMixture = [ ["coffee","sugar","milk"], ["tea","sugar","honey"] ];
//call our function


list(function(treat,addin,addin2){
    console.log("I like "+treat+" with " + addin + " and " + addin2);
},arrayMixture);


//output:
//I like coffee with sugar and milk
//I like tea with sugar and honey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接