关于操作符 “+” 的那些事儿

关于面试中经常遇到的 x + y 的值问题,一直是比较蛋疼的事儿,这里主要针对这两个比较常见的操作符 “ + ” 进行整理

+ 操作符

我们平常最常用到的字符串相加和数值相加的问题,我这里就简单的带过。

例: 我们现在要求 x + y 的值

最常用的两种情况:

  1. x 和 y 均为数值 : x = 1 , y = 2,则 x + y = 3
  2. x 和 y 均为字符串: x = ‘你’ y = ‘好’,则 x + y = ‘你好’

这俩种情况是最常见的,并且只要涉及到NaN的计算,无论怎样结果都是NaN。其他的情况估计只有在面试题里会见到了。开发中要是谁特么乱用这个估计会被打死,现在我们来说说面试中关于 + 操作符的其他情况。

Infinity

  • Infinity + Infinity = Infinity
  • -Infinity + -Infinity = -Infinity
  • Infinity + -Infinity = NaN

前两种都好理解,最后一种乍一眼感觉可能是 0。但实际上结果是NaN。所以可以这么理解,涉及到 Infinity 的加减,你感觉可以得到一个常数,肯定得不到,结果都是NaN,例如下面几种情况

  • Infinity * 0 —— 感觉结果是0,实际上是 NaN
  • Infinity / Infinity —— 感觉结果是1,实际上是 NaN
  • Infinity + -Infinity —— 感觉结果是0,实际上是 NaN
  • Infinity - Infinity —— 感觉结果是0,实际上是 NaN

数字 + 字符串

很简单,会把数字转换成字符串,然后再相加

“1” + 123 => “1” + “123” => “1123”

基本数据类型 + 基本数据类型 (非字符串)

基本数据类型(先不说字符串)和数字相加或者自己加自己时,会按照如下逻辑调用自己的Number方法

  • 把 null 转成 0
  • 把 undefined 转成NaN
  • 把 true 转成 1 , false 转成 0
	false + 1  // 1
	true + 1 // 2
	false + false // 0
	true + true // 2
	undefined + undefined // NaN
	undefined + null // NaN
	null + 123 // 123
	false + null // 0

其他情况会调用toString(),然后再执行字符串运算

	false + "1" // "false1"
	true + {} // "true[object Object]"

引用数据类型(对象) + X

对象 + X 会调用对象的toString()方法,将返回的值来进行相加

情况一:大部分对象

	{} + 1 // "[object Object]1"
	{} + {} // "[object Object][object Object]"
	[] + {} // "[object Object]"

关于第三行的例子,这里有个比较好玩的现象就是空数组的toString()方法,得到的是空字符串,Number方法也是,会先调用toString()方法,然后将得到的值转成数字

	[].toString() // "" 
	[1,2,3].toString() // "1,2,3" 
	Number([]) // 0
	Number([123]) // 123    ([123] --> "123" --> 123)
	Number([123, 123]) // NaN    ([123,123] --> "123,123" --> 123)

情况二:指定valueOf的对象

对于指定valueOf的对象,先看下面几个例子

	var obj = {
		valueOf: () => 3
	};
	var obj1 = {
		valueOf: () => false
	};
	var obj2 = {
		valueOf: () => "1"
	};
	var obj3 = {
		valueOf: () => null
	};
	var obj4 = {
		valueOf: () => undefined
	};
	obj + 3; // 6
	obj1 + 3; // 3
	obj2 + 3; // "13"
	obj3 + 3; // 3
	obj4 + 3; // NaN

这里会先调用对象的valueOf方法,如果返回的值是 基本数据类型(number, string, boolean, undifined, null),则用返回的基本数据类型的值来进行接下来的运算。

其他情况直接调用返回值的toString()方法,再执行字符串相加。

	var obj = {
		valueOf: () => obj
	};
	var obj1 = {
		valueOf: () => {}
	};
	obj + 3; // "[object Object]3"
	obj1 + 3; // "[object Object]3"

碰到的一些沙雕的问题

本人喜欢在Chrome的控制台里来进行一些调试,有一次

图1
emmm,如果按照上面的说法,理论上结果应该是。
{} 调用toString()方法得到的结果是 “[object Object]”
[] 调用toString()方法得到的结果是 “”
两个相加正常情况下应该是 “[object Object]”
但为啥是 0 呢?
看了下图应该就明白了
在这里插入图片描述
在JavaScript解析过程中。图一中的 {} 其实并不是对象,而是一个代码块,不参与运算,控制台打印的是 + [] 的值,所以是0

在这里插入图片描述
这两种表达理论上是一样的,所以会出现上述问题

在这里插入图片描述
这种方式同理,带上分号 把第一个 {} 解析成了代码块,所以最后的值就是 + {} 得到 NaN

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值