【问题标题】:JavaScript: Arrays. Why does concatenating an empty array with a populated array result in a string? [duplicate]JavaScript:数组。为什么连接一个空数组和一个填充数组会产生一个字符串? [复制]
【发布时间】:2017-09-27 04:29:55
【问题描述】:

我正在研究扁平化数组的问题。我遇到了一些非常奇怪的事情,似乎无法在网上找到答案。

为什么

[] + [1,2] = '1,2'

我似乎无法理解为什么将空数组添加到填充数组会导致字符串包含填充数组的内容。

导致这种情况的幕后发生了什么?

我的代码示例:

arr = [1, [2], [3, 4]];
arr.reduce(flatten, []); // [1, 2, 3, 4]

function flatten(a, b) {
    return a.concat(b);
}

据我了解,reduce 会将“[]”设置为“初始值”,因此对于原始数组中的每个元素,它会将其与一个空数组连接起来,从而“展平”数组。

【问题讨论】:

  • JavaScript 不是 Python,+ 运算符不连接列表。数组被强制转换为字符串。试试[1,2].toString();
  • + 既是算术加法又是 string 连接运算符。因此数组会自动转换为字符串以匹配运算符的参数类型。查看Array.prototype.concat 了解数组连接。

标签: javascript arrays concatenation


【解决方案1】:

当您在对象之间使用+(数组就是对象)时,JavaScript 会在内部调用toString() 和/或valueOf()

var coercion1 = {} + {foo: 'Foo', bar: 'Bar'},
    coercion2 = [] + ['foo', 'bar'];

console.log(coercion1);
console.log(coercion2);

这与以下内容相同:

var coercion1 = "".concat({}.toString(), {foo: 'Foo', bar: 'Bar'}.toString()),
    coercion2 = "".concat([].toString(), ['foo', 'bar'].toString());

console.log(coercion1);
console.log(coercion2);

这又与以下内容相同:

var coercion1 = "".concat({}.valueOf(), {foo: 'Foo', bar: 'Bar'}.valueOf()),
    coercion2 = "".concat([].valueOf(), ['foo', 'bar'].valueOf());

console.log(coercion1);
console.log(coercion2);

要将对象转换为字符串,JavaScript 采取以下步骤:

  • 如果对象有 toString() 方法,JavaScript 会调用它。如果它返回一个原始值,JavaScript 会将该值转换为 字符串(如果它还不是字符串)并返回结果 转换。 [...]
  • 如果对象没有 toString() 方法,或者如果该方法没有返回原始值,那么 JavaScript 会查找 valueOf() 方法。如果该方法存在,JavaScript 就会调用它。如果返回值是一个原始值,JavaScript 会将该值转换为 字符串(如果还没有)并返回转换后的值。
  • 否则,JavaScript 无法从 toString()valueOf() 获取原始值,因此会引发 TypeError。

大卫弗拉纳根JavaScript:权威指南

【讨论】:

    【解决方案2】:

    使用 + 将产生一个字符串,并且控制台会排除括号。和

    一样
    ''+[1,2]
    

    【讨论】:

    • 排除括号的不是控制台。
    • 可能表达不正确,但就是这样。如果您执行 {uno:11, dos:22} + "" 括号。从视觉上讲
    • 嗯,不。这给出了默认的[object Object]。我们谈论的是数组,而不是 POJO,它们会字符串化为逗号分隔的值。如果需要括号,请使用JSON.stringify 而不是字符串强制。
    • 在你的 [object Object] 上做一个 .length,尽管括号只是转换为字符串的对象的可视化表示,但括号也会被计算在内
    • 同样,数组有一个自定义的toString 实现,它们不会产生与对象相同的字符串。事实上,可以使用它来测试对象是否数组:Object.prototype.toString.call([1,2]) === '[object Array]'[1,2].toString() === '1,2'
    【解决方案3】:

    发生这种情况是因为 JavaScript 的 implicit type coersion+ 运算符触发。您不能简单地对数组执行+ 操作,因此它们将转换为字符串(其中包含数组的逗号分隔字符串转换值)。

    【讨论】:

      猜你喜欢
      • 2016-12-30
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多