【问题标题】:For..In loops in JavaScript - key value pairsJavaScript 中的 For..In 循环 - 键值对
【发布时间】:2011-11-06 16:46:26
【问题描述】:

我想知道是否有办法在 JavaScript 中执行 PHP foreach 循环之类的操作。我正在寻找的功能类似于这个 PHP Snippet:

foreach($data as $key => $value) { }

我正在查看 JS for..in 循环,但似乎无法指定 as。如果我使用“正常”for 循环 (for(var i = 0; i < data.length; i++) 执行此操作,有没有办法获取键 => 值对?

【问题讨论】:

    标签: javascript foreach


    【解决方案1】:
    for (var k in target){
        if (target.hasOwnProperty(k)) {
             alert("Key is " + k + ", value is " + target[k]);
        }
    }
    

    hasOwnProperty 用于检查您的target 是否真的具有该属性,而不是从其原型继承它。更简单一点的是:

    for (var k in target){
        if (typeof target[k] !== 'function') {
             alert("Key is " + k + ", value is" + target[k]);
        }
    }
    

    它只是检查k 不是方法(好像target 是array 你会收到很多方法警报,例如indexOf、push、pop 等)

    【讨论】:

    • 另一种只迭代“自己的”属性的方法是Object.keys。 Object.keys(target).forEach(function (key) { target[key]; });.
    • 如果使用Object.create(null) 创建target 将无法工作,代码应更改target.hasOwnProperty(k) -> Object.prototype.hasOwnProperty.call(target,k)
    • 为什么不使用问题示例中给出的变量? k、target 和 property 是什么?对我来说,非 javascripter 这个领域的 undefined :)
    • Object.keys(target).forEach((key) => { target[key]; });对于角
    【解决方案2】:

    如果您可以原生使用 ES6 或使用 Babel(js 编译器),那么您可以执行以下操作:

    const test = {a: 1, b: 2, c: 3};
    
    for (const [key, value] of Object.entries(test)) {
      console.log(key, value);
    }

    这将打印出这个输出:

    a 1
    b 2
    c 3
    

    Object.entries() 方法返回给定对象自己的可枚举属性 [key, value] 对的数组,其顺序与 for...in 循环提供的顺序相同(区别在于 for- in 循环也枚举原型链中的属性)。

    希望对您有所帮助! =)

    【讨论】:

    • 这很完美,只是想知道 - 与“for key in object 然后 get value by object[key]”相比,哪一个提供更好的性能?
    • 在这种特定情况下,我认为它会因为Object.entries 调用而变慢。不过我没有进行任何测试。
    • 这是对当前问题的最佳答案,该问题询问在 for 循环中同时获取键和值。
    • 应更新已接受的答案,因为这实际上回答了问题,尽管在提出问题时它不可用。
    • 您可能想检查这个问题:stackoverflow.com/questions/47213651/… 这似乎表明建议使用这种类型的语法: Object.keys(myObject).forEach(key => {...
    【解决方案3】:

    没有人提到Object.keys,所以我会提到它。

    Object.keys(obj).forEach(function (key) {
       // do something with obj[key]
    });
    

    【讨论】:

    • 注:IE8及以下不支持。
    • 此时您应该使用 ES5 shim。如果你生活在美好的 ES6 未来,请使用 for of tc39wiki.calculist.org/es6/for-of
    • 值得注意的是,“除了抛出异常,没有办法停止或中断 forEach() 循环”
    • Object.keys(obj).forEach((key) => { });对于角
    • 它在 ES6 上不起作用或者我不明白。 Felix 在下面有一个更好、更易读的答案: data.forEach(function(value, index) { console.log(index); // 0 , 1, 2... });
    【解决方案4】:

    for...in 将为您工作。

    for( var key in obj ) {
      var value = obj[key];
    }
    

    在现代 JavaScript 中,您也可以这样做:

    for ( const [key,value] of Object.entries( obj ) ) {
    
    }
    

    【讨论】:

      【解决方案5】:
      var obj = {...};
      for (var key in obj) {
          var value = obj[key];
      
      }
      

      php 语法只是糖。

      【讨论】:

      • 这也将迭代所有继承的属性。为避免这种情况,请使用 .hasOwnProperty()。
      【解决方案6】:

      我假设您知道 i 是键,并且您可以通过 data[i] 获取值(并且只想要一个快捷方式)。

      ECMAScript5 为数组引入了forEach [MDN](看来你有一个数组):

      data.forEach(function(value, index) {
      
      });
      

      MDN 文档为不支持它的浏览器提供了一个 shim。

      当然这对对象不起作用,但你可以为它们创建一个类似的函数:

      function forEach(object, callback) {
          for(var prop in object) {
              if(object.hasOwnProperty(prop)) {
                  callback(prop, object[prop]);
              }
          }
      }
      

      由于您使用 标记了问题,jQuery 提供了$.each [docs] 循环遍历数组和对象结构。

      【讨论】:

      • 这是数组forEach,而不是对象forEach。
      • 所以?显然 OP 正在遍历一个数组。
      • 此外,Mozilla(Firefox、SpiderMonkey-C、Rhino 和 c)有一个非标准扩展,允许 for each 语法。 for each (let val in myObj) console.log(val);.
      • @katspaugh:是的,但由于它只是 Mozilla,它似乎不是很有用。
      • 非常感谢您的回答。我会阅读你提供的信息。您在答案开始时的假设是正确的,我知道这一点,除了我对这个项目有太多的想法,以至于我无法集中注意力并忘记了它。谢谢。
      【解决方案7】:

      您可以为此使用for..in。

      for (var key in data)
      {
          var value = data[key];
      }
      

      【讨论】:

        【解决方案8】:
        for (var key in myMap) {
            if (myMap.hasOwnProperty(key)) {
                console.log("key =" + key);
                console.log("value =" + myMap[key]);
            }
        }
        

        在 javascript 中,每个对象都有一堆具有元信息的内置键值对。当您遍历对象的所有键值对时,您也在遍历它们。使用 hasOwnProperty() 过滤掉这些。

        【讨论】:

          【解决方案9】:
          let test = {a: 1, b: 2, c: 3};
          Object.entries(test).forEach(([key, value]) => console.log(key, value))
          
          // a 1
          // b 2
          // c 3
          

          【讨论】:

          • 您可以在发布的代码中添加一些解释,而不是发布可能无法理解的普通代码。
          • Object.entries 根据原始对象的键/值对拉出一个数组数组:[['a', 1],['b',2],['c',3]]。 forEach 解构每个键/值数组,并将两个变量设置为 key 和 value,以便在 in 函数中使用 - 这里在 console.log 中输出。
          【解决方案10】:

          在提出这个问题后的最后几年里,Javascript 增加了一些新功能。其中之一是Object.Entries 方法。

          直接从MDN复制的是下面的代码sn-p

          
          const object1 = {
            a: 'somestring',
            b: 42
          };
          
          for (let [key, value] of Object.entries(object1)) {
            console.log(`${key}: ${value}`);
          }
          

          【讨论】:

            【解决方案11】:

            处理对象的键和值有三个选项:

            1. 选择值:
            Object.values(obj).forEach(value => ...);
            
            1. 选择键:
            Object.keys(obj).forEach(key => ...);
            
            1. 选择键和值:
            Object.entries(obj).forEach(([key, value]) => ...);
            

            【讨论】:

              【解决方案12】:

              ES6 会提供 Map.prototype.forEach(callback) 可以这样使用

              myMap.forEach(function(value, key, myMap) {
                                      // Do something
                                  });
              

              【讨论】:

              • myMap 的参数是什么?
              • 地图不是对象。它们是完全不同的东西。
              • forEach 函数不包含数组的“键”,而是包含您当前正在迭代的元素的索引。
              【解决方案13】:

              您可以为此使用“for in”循环:

              for (var key in bar) {
                   var value = bar[key];
              }
              

              【讨论】:

                【解决方案14】:

                下面是一个尽可能接近的示例。

                for(var key in data){
                  var value = data[key];    
                  //your processing here
                }
                

                如果您使用 jQuery,请参阅:http://api.jquery.com/jQuery.each/

                【讨论】:

                  【解决方案15】:

                  如果你使用Lodash,你可以使用_.forEach

                  _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
                    console.log(key + ": " + value);
                  });
                  // => Logs 'a: 1' then 'b: 2' (iteration order is not guaranteed).
                  

                  【讨论】:

                    【解决方案16】:

                    为什么不这样

                    var donuts = [
                    { type: "Jelly", cost: 1.22 },
                    { type: "Chocolate", cost: 2.45 },
                    { type: "Cider", cost: 1.59 },
                    { type: "Boston Cream", cost: 5.99 }];
                    
                    donuts.forEach(v => {console.log(v["type"]+ " donuts cost $"+v["cost"]+" each")});
                    

                    【讨论】:

                    • 为什么不包括教育解释? OP 想要从一维结构中获取键和值——你的答案是忽略这个要求。
                    【解决方案17】:

                    请尝试以下代码:

                    <script> 
                     const games = {
                      "Fifa": "232",
                      "Minecraft": "476",
                      "Call of Duty": "182"
                     };
                    
                    Object.keys(games).forEach((item, index, array) => {
                      var msg = item+' '+games[item];
                      console.log(msg);
                    });
                    

                    【讨论】:

                    • 如果您不使用array,为什么会出现?与 5 年前的相同建议相比,您的回答有何价值?
                    【解决方案18】:

                    是的,您也可以在 javascript 中使用关联数组:

                    var obj = 
                    {
                        name:'some name',
                        otherProperty:'prop value',
                        date: new Date()
                    };
                    for(i in obj)
                    {
                        var propVal = obj[i]; // i is the key, and obj[i] is the value ...
                    }
                    

                    【讨论】:

                    • @PaulPRO ... javascript 中的所有内容都是键值对(因此,对象实际上是键值对的关联数组...)
                    • @AlexPacurar 和关联数组有一个顺序。一个对象是无序的。 那是很大的不同
                    • @Raynos 你可能是对的......这将有助于准确解释一个对象是如何无序的......鉴于上面的例子,人们会期望 for循环为 [name, otherProperty, and finally date]... 那么在什么情况下对象的属性顺序会混合?
                    • @AlexPacurar 循环遍历对象的特定顺序是特定于浏览器的。有些按字母顺序,有些按定义顺序,等等
                    • @Raynos:关联数组一定是有序的吗?我经常看到这个词被更广泛地使用。例如,在the Associative array Wikipedia article。
                    【解决方案19】:
                    var global = (function() {
                       return this;
                    })();
                    
                    // Pair object, similar to Python
                    
                    function Pair(key, value) {
                        this.key = key;
                        this.value = value;
                    
                        this.toString = function() {
                           return "(" + key + ", " + value + ")";
                        };
                    }
                    
                    /**
                     * as function
                     * @param {String} dataName A String holding the name of your pairs list.
                     * @return {Array:Pair} The data list filled
                     *    with all pair objects.
                     */
                    Object.prototype.as = function(dataName) {
                        var value, key, data;
                        global[dataName] = data = [];
                    
                        for (key in this) {
                           if (this.hasOwnProperty(key)) {
                              value = this[key];
                    
                              (function() {
                                 var k = key,
                                     v = value;
                    
                                data.push(new Pair(k, v));
                              })();
                           }
                        }
                    
                        return data;
                    };
                    
                    var d = {
                       'one': 1,
                       'two': 2
                    };
                    
                    // Loop on your (key, list) pairs in this way
                    for (var i = 0, max = d.as("data").length; i < max; i += 1) {
                       key = data[i].key;
                       value = data[i].value;
                    
                       console.log("key: " + key + ", value: " + value);
                    }
                    
                    // delete data when u've finished with it.
                    delete data;
                    

                    【讨论】:

                      猜你喜欢
                      • 2011-07-12
                      • 2015-02-25
                      • 2016-03-30
                      • 2011-10-21
                      • 2012-11-18
                      • 2013-07-10
                      • 2013-08-31
                      • 1970-01-01
                      相关资源
                      最近更新 更多