具有null或未定义值的JavaScript字符串连接行为
您可能知道,在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要求的标准
''+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"