【问题标题】:Simple theory behind getting the property name from a for-in loop?从 for-in 循环中获取属性名称的简单理论?
【发布时间】:2012-11-11 19:10:07
【问题描述】:

首先,我想说我在理论上很厉害。我不喜欢抽象。在尝试使用它们之前,我想知道它们是如何工作的。我一直在到处寻找一个简单的理论来获取 for-in 循环的属性名称(而不是值)。我将在代码中演示它,希望有人可以解释它是如何工作的……

var obj = { one: 1, two: 2, three: 3 }; // A basic object instantiated with 3 public properties.

for (var prop in obj) {
    console.log(prop); // logs "one", "two" and "three" ???
}

我认为它会将 prop 变量评估为 1、2 和 3,但它会注销实际的属性名称。我知道 obj[prop] 是评估这些属性的实际值的,但这对我来说就像是一个开始。 prop 是存储另一个引用的引用?

我试图从 for 循环中的变量 i 有点像数组的索引来考虑这一点。

这又是什么,和我问的一样吗?

var obj = { "one": 1, "two": 2, "three": 3 };

属性名称字符串如何?...你不能说 var "string" = "Hello, World!";因为那是非法的。

【问题讨论】:

  • 我没有为 JavaScript 解释它的背景,但听起来你的答案将与“反射”有关。
  • 你在理论上很厉害,但你不喜欢抽象?不..不..计算.....
  • I yi yi...我的语法很糟糕。我的意思是我不喜欢抽象的东西。就像,如果你知道我的意思,我希望尽可能详细地解释它。
  • @W3Geek:听起来你在理论的对立面上很厉害——实际实施:)

标签: javascript arrays oop object loops


【解决方案1】:

对象属性的名称​​是字符串,当prop 是有效标识符时,obj.prop 只是obj["prop"] 的语法糖。比如你不能说obj.my property,你必须写obj["my property"]

for..in 枚举对象及其原型链中的可枚举键,将当前字符串键分配给左侧。所以你可以这样做:

var a = [], i = 0;
for( a[i++] in obj );

//a is an array: ["one", "two", "three"]

随着循环的进行,左侧被评估为一个引用(i 作为一个副作用而增加)并分配当前键。所以它看起来像a[0] = keya[1] = key2等等。

如果您想了解所有详细信息,请参阅以下规范:

【讨论】:

    【解决方案2】:

    JavaScript 对象是一个字典,键是任意字符串,不一定是有效的 JavaScript 标识符。因此,有些东西可以用作属性名称(即任何有效字符串),但不能用作变量名称。

    For/in 被定义为循环遍历(可枚举的)属性names(即键),对于数组也是如此,这样

    for (var i in [10,20,30]) document.write (i);
    

    将打印“012”,而不是“102030”。

    可以将属性定义为不可枚举,在这种情况下 for/in 将跳过它。在 ECMAScript 5 中,您可以自己定义不可枚举的属性。枚举顺序未定义。请注意,for/in 还考虑了原型的属性(这就是您经常会在循环内立即看到 hasOwnProperty 条件的原因)。

    【讨论】:

    • 这很酷。我从不知道您可以对数组使用 for-in 循环。一个人!
    • 缺点是你永远不应该对数组使用 for-in 循环,它[比 for 循环] 慢一个数量级,与扩展方法中断并且迭代顺序未定义跨度>
    • ECMAScript 5 应该可以解决这个问题:[10,20,30].forEach (function (i) { document.write (i); }) 打印“102030”` 并且比 for 循环要好得多——至少对于极客和美学家而言。
    【解决方案3】:

    prop是存储另一个引用的引用吗?

    不,prop 是您在迭代中到达的元素的键。一个字符串。

    就是这样。没有比这更复杂的了。

    你不能说 var "string" = "Hello, World!";因为那是非法的

    这也是一个完全不同的语言特性...

    可以说,提供对象至少部分是为了解决您确定的限制。

    【讨论】:

      【解决方案4】:

      我不得不承认我没有完全理解这个问题,但我还是尽量回答。 object 几乎可以与 hash (-table) 相媲美。如您所知,它由一个标识符和一个存储在该标识符后面的值组成。

      在 ECMAscript 中,该标识符是 object 中的 key

      对于一个数组,在循环遍历它时,您只希望收到一件有趣的事情,因为它的“keys”只是索引数字(实际上这里也是 Strings,但这只是一个旁注)。但是,由于对象 keys 可以是任何东西,因此在循环它们时会发生冲突。你想获取 key 还是 value

      这就是为什么会有for-in 循环。您正在遍历 keys 并且使用该键您可能还可以访问后面的值。


      但是 - 你并不完全独自面对这种困惑。这就是 ECMAscript Next 将引入对象的for-of 循环的原因,它颠倒了这个逻辑。您将直接遍历值,而不是 keys

      var obj = { one: 1, two: 2, three: 3 };
      
      for(var value of obj) {
          console.log(value); // 1, 2, 3
      }
      

      【讨论】:

      • 它们(for in 和 for of)都不理想,应该只提供语法来在同一个循环中公开键和值:P 有点像 php:for( value in obj)for( key, value in obj) 或其他
      • 我同意 - 我喜欢 PHP 的数组循环语法。关于它唯一的好处。
      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 2017-02-10
      • 2015-06-13
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 2017-12-13
      相关资源
      最近更新 更多