首页 > 解决方案 > 什么时候 for 循环会导致类型强制 javascript?

问题描述

当我这样做时:

const foo = [0, 1, 2]

for (i = 0; i < foo.length; i ++){
    console.log(foo[i], typeof foo[i])
}

我明白了:

0 number
1 number
2 number

但是当我这样做时:

for (let item in foo){
    console.log(item, typeof item)
}

我明白了:

0 string
1 string
2 string

这里发生了什么??我需要知道哪些规则来预测这一点?

编辑:我正在运行节点 12.18.3

标签: javascripttypestype-coercion

解决方案


这里没有强制执行。您实际上是在使用两个不同的循环迭代两种不同的原始类型。

for带计数器的传统循环,用数字计数。

for/in循环用于迭代对象的属性。对象具有键/属性,它们始终是字符串。因此,当您看到012时,您看到的是字符串"0""1""2"

因此,当您for/in在实例上使用循环时array,它由Array对象的键枚举,其中包括数组索引的字符串表示以及Array实例的任何可枚举属性。然后,您可以结束枚举数组中除了其中的项目之外的其他属性,如下所示:

const foo = [0, 1, 2];

// Add a property to the array instance
foo.bar = "baz";

for (let item in foo){
  // This will log ALL the enumerable properties
  // of the object, in this case, including properties
  // that are not the array values.
  console.log(item, foo[item]);
}

这是另一种看待这一点的方式。下面是一个用 枚举的对象字面量for/in。请注意,当创建文字时,键不会在它们周围加上引号,但是当它们的类型被测试时(它们是键名,而不是键值),它们被报告为字符串,因为它们隐含地是:

let obj = {
 key1: "something",
 key2: "something else",
 foo: 42,
 false: true,
 99: 100
};

for(let prop in obj){
  // Note that even the unquoted key name of 
  // false is implicitly a string, not a Boolean
  // and the 99 key is a string, not a number
  console.log(prop, "(" + typeof prop + ")", obj[prop], "(" + typeof obj[prop] + ")");
}

如文档中所述(上面的链接):

for...in 语句迭代对象的所有可枚举属性,这些属性以字符串为键(忽略以符号为键的),包括继承的可枚举属性。


推荐阅读