具有null或未定义值的JavaScript字符串连接行为

具有null或未定义值的JavaScript字符串连接行为,javascript,null,undefined,string-concatenation,Javascript,Null,Undefined,String Concatenation,您可能知道,在JavaScript中,''+null=“null”和''+undefined=“undefined”(在大多数浏览器中,我可以测试:Firefox、Chrome和IE)。我想知道这种奇怪现象的起源(布伦丹·艾奇的脑袋里到底是什么?!)以及在未来版本的ECMA中是否有任何改变它的目标。要将字符串与变量连接起来,并使用第三方框架(如下划线或其他)使用锤子敲打果冻钉,必须执行'sthg'+(var | |'),这确实是相当令人沮丧的 编辑: 为了满足StackOverflow要求的标准

您可能知道,在JavaScript中,
''+null=“null”
''+undefined=“undefined”
(在大多数浏览器中,我可以测试:Firefox、Chrome和IE)。我想知道这种奇怪现象的起源(布伦丹·艾奇的脑袋里到底是什么?!)以及在未来版本的ECMA中是否有任何改变它的目标。要将字符串与变量连接起来,并使用第三方框架(如下划线或其他)使用锤子敲打果冻钉,必须执行
'sthg'+(var | |')
,这确实是相当令人沮丧的

编辑:

为了满足StackOverflow要求的标准并澄清我的问题,这是一个三重问题:

  • 让JS将
    null
    undefined
    转换为
    string
    串联中的字符串值的奇怪现象背后的历史是什么
  • 在未来的ECMAScript版本中,这种行为有可能发生改变吗
  • <> LI>连接“<代码>字符串< /代码> >潜在的<代码> null < /代码>或<代码>未定义< /代码>对象而不陷入此问题(获得某些<代码>未定义的 <代码> >在字符串中间的空“< /代码>”是什么最漂亮的方法?我所说的“最漂亮”的主观标准是:短、干净、有效。不必说
    ''+(obj?obj:'')
    不是很漂亮
要添加null和“”,它们需要满足最低通用类型标准,在本例中为字符串类型

由于这个原因,null被转换为“null”,并且由于它们是字符串,所以将两者连接起来

数字也是如此:

4+''='4'


由于其中有一个无法转换为任何数字的字符串,因此4将转换为字符串。

您可以使用
Array.prototype.join
忽略
未定义的
null

['a','b',void 0,null,6]。连接(“”);/'ab6'
根据报告:

如果元素
未定义
,则下一个元素为空字符串; 否则,让下一个是ToString(元素)


鉴于此,

  • 让JS将
    null
    undefined
    转换为
    string
    串联中的字符串值的奇怪现象背后的历史是什么? 事实上,在某些情况下,当前的行为是有道理的

    function showSum(a,b) {
        alert(a + ' + ' + b + ' = ' + (+a + +b));
    }
    例如,如果调用上面的函数时没有参数,
    undefined+undefined=NaN
    可能比
    +=NaN
    更好

    一般来说,我认为如果要在字符串中插入一些变量,显示
    undefined
    null
    是有意义的。也许,艾奇也这么认为

    当然,在某些情况下,忽略这些内容会更好,例如将字符串连接在一起时。但是对于这些情况,您可以使用
    Array.prototype.join

  • 在未来的ECMAScript版本中,这种行为有可能发生改变吗? 很可能不是

    由于已经有了
    Array.prototype.join
    ,修改字符串连接的行为只会带来缺点,而不会带来好处。此外,它会破坏旧代码,因此它不会向后兼容

  • 将字符串与潜在的
    null
    未定义的
    连接起来最漂亮的方法是什么?
    
    Array.prototype.join似乎是最简单的一个。它是否最漂亮可能取决于人们的看法

在未来的ECMAScript版本中,这种行为有可能发生改变吗

我想说的是,机会非常渺茫。有几个原因:

我们已经知道ES5和ES6是什么样子了 未来的ES版本已经完成或处于草稿中。没人会改变这种行为。这里需要记住的是,这些标准需要几年才能在浏览器中建立起来,因为您可以使用这些标准编写应用程序,而无需依赖将其编译为实际Javascript的代理工具

试着估计一下持续时间。即使ES5也没有得到大多数浏览器的完全支持,这可能还需要几年的时间。ES6甚至还没有完全指定。出乎意料的是,我们至少还要再等五年

浏览器做自己的事情 众所周知,浏览器会对某些主题做出自己的决定。您不知道是否所有浏览器都会以完全相同的方式完全支持此功能。当然,一旦它成为标准的一部分,您就会知道,但到目前为止,即使它被宣布成为ES7的一部分,充其量也只是猜测

浏览器可能会在这里做出自己的决定,特别是因为:

这种变化正在打破 标准最重要的一点是,它们通常试图向后兼容。对于web来说尤其如此,在web中,相同的代码必须在各种环境中运行

如果该标准引入了一个新功能,而旧浏览器不支持它,那是一回事。告诉您的客户更新其浏览器以使用该网站。但是如果你更新了浏览器,突然有一半的网络断开了,那就是一个bug

当然,这个特殊的更改不太可能破坏很多脚本。但这通常是一个糟糕的论点,因为标准是普遍的,必须考虑到每一个机会。想想看

"use strict";
作为切换到严格模式的指令。它向huw展示了一个标准在试图使所有东西都兼容方面所付出的努力,因为他们可以将strict模式设置为默认模式(甚至是唯一模式)。但是有了这个聪明的指令,您可以让旧代码在不做任何更改的情况下运行,并且仍然可以利用新的、更严格的模式

向后兼容性的另一个例子是
=
const Strings = {};
Strings.orEmpty = function( entity ) {
    return entity || "";
};

// usage
const message = "This is a " + Strings.orEmpty( test );
const concatObject = (obj, separator) =>
    Object.values(obj)
        .filter((val) => val)
        .join(separator);


let myAddress = {
    street1: '123 Happy St',
    street2: undefined,
    city: null,
    state: 'DC',
    zip: '20003'
}

concatObject(myAddress, ', ')
> "123 Happy St, DC, 20003"