您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 海北分类信息网,免费分类信息发布

理解Javascript中的“+”运算符

2024/4/23 12:04:54发布15次查看
在网上或面试题中经常会看到一些“奇怪”的语句,比如
{}+{} // [object object][object object] {}+[] // 0 []+{} // [object object] []+[] // 

在javascript中+运算符是个重载运算符,可用来拼接字符串,以及把两个“数字”相加。至于是哪种情况要看运算符两边参数的类型。  
在日常的开发中我们也不会碰到这么麻烦的事,但弄弄清楚总是好的。在规范 中巴拉巴拉地说了一堆,简单来说就是:
1. 对于原生类型,参数中只要有一方是字符串,则按字符串连接处理,否则按数字相加处理,不是数字的会先转成数字再相加。
原生类型有:undefined, null, boolean, number, string。
下面是一些示例:
0 + '1'     // '01' null + 1    // 1 true + 1    // 2 false + 1   // 0 undefined + 2   // nan,  因为undefined转成number是nan

2. 对于引用类型,则需要先转换成原生类型,再按以上规则相加。如何转换在规范中有详细的说明,但规范看起来是有点费劲。 简单来说就是:默认情况下都转化成字符串,要搞特殊的话,请重写valueof()方法。
来个例子:
function complex(a, b) {   this.a = a;   this.b = b; } complex.prototype.valueof() {   return this.a; } new complex(2, 3) + new complex(4, 5); // 6

但由于js不支持真正的操作符重载,即不能相加得到自定义类型的对象, 所以以上示例在实践代码中非常少用。
不过目前的知识足够回答原先的问题了。但是慢着,{}+[] 为什么和 []+{}不一样? 这其实是个语法问题。前者相当于:
{} +[]

其实是两个句子, [] 转换成数字是 0。很容易验证 ({}+[]) === '[object object]'
+[]  // 0

有人可能要问,那 new date() 的 valueof() 不是转换成数字吗?为什么相加结果还是字符串类型呢?
new date().valueof(); // 1491904757087 1 + new date(); // 1tue apr 11 2017 18:02:16 gmt+0800 (cst)

这是date类做了特殊处理, @@toprimitive, 默认情况下对 date 的相加以字符串方式连接,但比较时则会转换成数字。
new date() < new date('2018-01-01') // true, 现在是2017

将引用类型转换成原生类型在很多操作符中都有用到,比如 <, >, 所以有必要对其研究一番, 以下js代码大概描述了其行为。/**  * @param input     即要转换的对象  * @preferredtype   期望转换成的类型,可以是string或number  */ function toprimitive(input, preferredtype) {   if (typeof input !== 'object') {     return input;   // 本来就是原生类型   }   var hint = preferredtype || 'default';   if (typeof input['@@toprimitive'] === 'function') {   // @@toprimitive是个内部方法,这里只是示例说明其工作原理     return input['@@toprimitive'](input, hint);   // 这就是为什么date能特殊处理的原因   }   if (hint === 'string') {     return input.tostring();   }   return input.valueof(); }

详细的请参考规范
在网上或面试题中经常会看到一些“奇怪”的语句,比如
{}+{} // [object object][object object] {}+[] // 0 []+{} // [object object] []+[] // 

在javascript中+运算符是个重载运算符,可用来拼接字符串,以及把两个“数字”相加。至于是哪种情况要看运算符两边参数的类型。  
在日常的开发中我们也不会碰到这么麻烦的事,但弄弄清楚总是好的。在规范 中巴拉巴拉地说了一堆,简单来说就是:
1. 对于原生类型,参数中只要有一方是字符串,则按字符串连接处理,否则按数字相加处理,不是数字的会先转成数字再相加。
原生类型有:undefined, null, boolean, number, string。
下面是一些示例:
0 + '1'     // '01' null + 1    // 1 true + 1    // 2 false + 1   // 0 undefined + 2   // nan,  因为undefined转成number是nan

2. 对于引用类型,则需要先转换成原生类型,再按以上规则相加。如何转换在规范中有详细的说明,但规范看起来是有点费劲。 简单来说就是:默认情况下都转化成字符串,要搞特殊的话,请重写valueof()方法。
来个例子:
function complex(a, b) {   this.a = a;   this.b = b; } complex.prototype.valueof() {   return this.a; } new complex(2, 3) + new complex(4, 5); // 6

但由于js不支持真正的操作符重载,即不能相加得到自定义类型的对象, 所以以上示例在实践代码中非常少用。
不过目前的知识足够回答原先的问题了。但是慢着,{}+[] 为什么和 []+{}不一样? 这其实是个语法问题。前者相当于:
{} +[]

其实是两个句子, [] 转换成数字是 0。很容易验证 ({}+[]) === '[object object]'
+[]  // 0

有人可能要问,那 new date() 的 valueof() 不是转换成数字吗?为什么相加结果还是字符串类型呢?
new date().valueof(); // 1491904757087 1 + new date(); // 1tue apr 11 2017 18:02:16 gmt+0800 (cst)

这是date类做了特殊处理, @@toprimitive, 默认情况下对 date 的相加以字符串方式连接,但比较时则会转换成数字。
new date() < new date('2018-01-01') // true, 现在是2017

将引用类型转换成原生类型在很多操作符中都有用到,比如 <, >, 所以有必要对其研究一番, 以下js代码大概描述了其行为。/**  * @param input     即要转换的对象  * @preferredtype   期望转换成的类型,可以是string或number  */ function toprimitive(input, preferredtype) {   if (typeof input !== 'object') {     return input;   // 本来就是原生类型   }   var hint = preferredtype || 'default';   if (typeof input['@@toprimitive'] === 'function') {   // @@toprimitive是个内部方法,这里只是示例说明其工作原理     return input['@@toprimitive'](input, hint);   // 这就是为什么date能特殊处理的原因   }   if (hint === 'string') {     return input.tostring();   }   return input.valueof(); }

以上就是理解javascript中的“+”运算符的详细内容。
海北分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录