【问题标题】:Javascript equivalent of PHP's list()Javascript 等效于 PHP 的 list()
【发布时间】:2010-12-29 14:13:00
【问题描述】:

真的很喜欢那个功能。

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

有与此等效的 Javascript 吗?

【问题讨论】:

  • 标准方法有什么问题var value = matches[0]; var unit = matches[1];
  • 嗯,这不是很简洁,是吗?
  • 我从来没有觉得list() 有用,上面只是对我大喊反对var power = { 'unit': 'watt', 'amount': 12 }
  • 很丑很长。我认为 list() 使代码更具可读性。
  • PHP 的 list() 非常方便,如果您想在不需要临时变量的情况下交换变量值:list($b, $a) = array($a, $b);

标签: php javascript list phpjs


【解决方案1】:

在“较新”版本的 Javascript 中有:Destructuring assignment - Javascript 1.7。它可能仅在基于 Mozilla 的浏览器中受支持,也许在 Rhino 中。

var a = 1;  
var b = 3;  

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

编辑:实际上,如果 V8 Javascript 库(以及 Chrome)支持这一点,我不会感到惊讶。但也不要指望它 现在supported 在所有现代浏览器中(当然,除了 IE)。

【讨论】:

  • 整洁!我真的很喜欢他们在新版本的 Javascript 中加入的所有很酷的东西!只是感觉我们将无法使用它们很长时间..
  • 2015 年,V8 仍然不支持。
  • Firefox 从 2006 年的第 2 版开始支持它。2015 年的 V8/Chrome 仍然不支持它。Chrome 是新的 IE。
  • 在 2018 年仍要小心使用它; IE 从来不支持它,很多人还在使用它。用于判断兼容性:kangax.github.io/compat-table/es6
  • 2019 年 3 月的报告。这适用于 Chrome 72(64 位)。
【解决方案2】:

【讨论】:

  • 这篇文章的第二个链接失效了(404 - 这不是你要找的网页)。
【解决方案3】:

试试这个:

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

【讨论】:

    【解决方案4】:

    CoffeeScript 提供解构赋值,语法如下:

    [a, b] = someFunctionReturningAnArray()
    

    这与非常新的 JavaScript 版本中提供的功能几乎相同。但是,CoffeeScript 生成的编译后的 JS 甚至与 IE6 的 JavaScript 引擎兼容,因此如果兼容性至关重要,它是一个不错的选择。

    【讨论】:

      【解决方案5】:

      这是我在 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 原型来实现的。

      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']; [值,单位] = 匹配;或者 function () { var [year, month] = $(this).val().split("/");在 Chrome 中,它会抛出一个错误:“ReferenceError: Invalid left-hand side in assignment”
      • 使用window 作为默认对象是一个非常糟糕的主意。
      • @Bergi 他只默认使用它。您可以提供一个对象作为最后一个参数,它将使用它。
      • @lac_dev 喜欢这个小脚本,非常适合我。非常高兴您考虑了超出数据的标签
      【解决方案6】:

      这是我的窍门;尽可能短,而无需编写函数来完成它。不过要注意“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];
      

      这种方式要短得多。此外,如果你有一堆变量,它们可能应该保存在数组中,或者更好的是它们应该是闭包的属性,而不是单独声明它们。

      【讨论】:

        【解决方案7】:
        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
        

        【讨论】:

          【解决方案8】:

          由于大多数 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"
          

          Check the fiddle


          另一种方法是向 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"
          

          Check the fiddle for that one

          【讨论】:

            【解决方案9】:

            ES6 现在通过array destructuring 直接支持这一点。

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

            【讨论】:

            • 截至 2019 年年中,这是最好的答案。接受的答案将在许多 linter 中抛出“[variable] is not defined (no-undef)”警告。这纠正了这一点。请注意,您还可以在 for...of 循环中进行数组解构
            猜你喜欢
            • 2010-10-21
            • 2013-07-15
            • 2015-01-16
            • 1970-01-01
            • 2012-01-15
            • 2010-11-07
            • 1970-01-01
            • 1970-01-01
            • 2014-10-20
            相关资源
            最近更新 更多