第 116 题:输出以下代码运行结果
yygmind opened this issue · 34 comments
1 + "1"
2 * "2"
[1, 2] + [2, 1]
"a" + + "b"
'11'
4
'1,22,1'
'aNaN'
//"a" + + "b"其实可以理解为
// + "b" -> NaN
//“a”+NaN
11
4
1,22,1
aNaN
求讲解
最后一个不懂
"a" + + "b"
"aNaN"
这个是为啥
"a" + + "b"
"aNaN"
这个是为啥
"a" + + "b"
是先+"b"
, 所以是NaN
=> "a" + NaN
=> "aNaN"
- 'b'为什么是NaN
- 1 + "1"
加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
所以值为:“11”
- 2 * "2"
乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
Javascript中所有对象基本都是先调用valueOf
方法,如果不是数值,再调用toString
方法。
所以两个数组对象的toString方法相加,值为:"1,22,1"
- "a" + + "b"
后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
所以值为:"aNaN"
以上均参考:《Javascript高级程序设计》
难度一般
+"b" => NAN
+(正)-(负)!, ++,--
优先级 比+、-、*、/ 运算优先级高
"a" + + "b" 相当于 "a" + Number("b")
- 1 + "1"
加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
所以值为:“11”
- 2 * "2"
乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
Javascript中所有对象基本都是先调用
valueOf
方法,如果不是数值,再调用toString
方法。所以两个数组对象的toString方法相加,值为:"1,22,1"
- "a" + + "b"
后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
所以值为:"aNaN"
以上均参考:《Javascript高级程序设计》
mark 一下
很基础的题目,不过数组那个case有点不一样,它最后还会再执行join方法进行隐式转换
const arr = [1,2,3]
const { toString, valueOf, join } = arr
arr.toString = function(...args) {
console.log('tostring');
return toString.call(arr, ...args)
}
arr.valueOf = function(...args) {
console.log('valueOf');
return valueOf.call(arr, ...args)
}
arr.join = function(...args) {
console.log('join');
return join.call(arr, ...args)
}
arr + [4,5,6]
更多类型转换相关可见这里
稍稍补充一小下:
加号作为一元运算符时,其后面的表达式将进行ToNumber(参考es规范)的抽象操作:
- true -> 1
- false -> 0
- undefined -> NaN
- null -> 0
- ’字符串‘ -> 字符串为纯数字时返回转换后的数字(十六进制返回十进制数),否则返回NaN
- 对象 -> 通过ToPrimitive拿到基本类型值,然后再进行ToNumber操作
+true // 1
+false // 0
+undefined // NaN
+null // 0
+'b' // NaN
+'0x10' // 16
+{valueOf: ()=> 5} // 5
- 1 + "1"
加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
所以值为:“11”
- 2 * "2"
乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
Javascript中所有对象基本都是先调用
valueOf
方法,如果不是数值,再调用toString
方法。所以两个数组对象的toString方法相加,值为:"1,22,1"
- "a" + + "b"
后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
所以值为:"aNaN"
以上均参考:《Javascript高级程序设计》
补充一下:js中一元加的优先级高于2元加,第四问主要考查的是js的运算优先级
运算优先级
"11"
4
"1,22,1"
"aNaN"
最后一个不懂
关于第四个为何+“b”等于“NaN”,大家可以参考这里。
原理是:
-
首先一元运算符+优先级高于二元运算符+,原式等于"a" + ( +"b");
-
而+“b”可以看上面的链接,对于类似"2b"、“b”、“b2”不是纯数字的串,进行一元加运算时无法转化为数字,返回“NaN”。
- 我有个问题,加法运算符是从左到右运算的,"a" + + "b"
- ① ("a" + )+ "b" =>结果报错
- ② "a" +( + "b") => 先算 + "b" 得 aNaN
- ③ "a" + (+"b") => 把+“b”看出整体,的aNaN
我的问题是,为什么不是第一个。而是第三个呢?
因为一元运算符优先级高。参考
- 我有个问题,加法运算符是从左到右运算的,"a" + + "b"
- ① ("a" + )+ "b" =>结果报错
- ② "a" +( + "b") => 先算 + "b" 得 aNaN
- ③ "a" + (+"b") => 把+“b”看出整体,的aNaN
我的问题是,为什么不是第一个。而是第三个呢?因为一元运算符优先级高。参考
这个我知道啊,你说说优先级怎么样?
- 1 + "1"
加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
所以值为:“11”
- 2 * "2"
乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
Javascript中所有对象基本都是先调用
valueOf
方法,如果不是数值,再调用toString
方法。所以两个数组对象的toString方法相加,值为:"1,22,1"
- "a" + + "b"
后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
所以值为:"aNaN"
以上均参考:《Javascript高级程序设计》
mark too
1 + "1"
//"11"
2 * "2"
//4
[1, 2] + [2, 1]
//"1,22,1"
"a" + + "b"
//"aNaN"
今天的题目还是比较简单
- 字符串拼接
1 + '1' // '1' + '1' -> 11
- 隐式转换为数字
2 * '2' // 2 * 2 -> 4
- 依旧是字符拼接 [].toString()
[1, 2] + [2, 1] // '1, 2' + '2, 1' -> 1, 22, 1
- 依旧是隐式转换为数字,再做拼接 + 'b' -> NaN
'a' + + 'b' // 'a' + NaN -> 'aNaN'
另外
- 表达式有多个带间隔的+/-时会从后至前依次进行正负运算操作
let a = 1;
let b = 2;
a + + - + - - + - b // 3
- 两个连续不间断的+/-会被判定为自增/自减运算符
let a = 1;
let b = 2;
a ++ - - ++ b // 1 - -3 -> 4
console.log( 1 + "1" )
//11
console.log( 2 * "2" )
//4
console.log([1, 2] + [2, 1])
//[3,3]. [1,2,1]
console.log("b" + + "a")
//"a b" [aNaN]
1 + "1" //11
2 * "2" // 4
[1, 2] + [2, 1] // 相当于转成stirng,所以12+21=1221
"a" + + "b" // +‘b’隐式转换为NaN,'a'+NaN=aNaN
关于这个 "a" + + "b" 为aNaN,是因为第二个+号是正号的意思,一元运算符(单目运算符的优先级高于双目运算符),+"b" ,"b"隐式转换number类型所以aNaN
指针最优,单目运算优于双目运算。如正负号。
先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7.
逻辑运算最后结合。
以上来自百度
- 'b'为什么是NaN
+"b" =>Number("b")=>NaN
摘抄
对数字进行一元加操作,结果返回数字本身,要注意对负数进行一元加操作结果还是负数啦,不要以为会得到整数;
对布尔类型进行一元加操作,true的话返回1,false返回0;
对null进行一元加操作,返0;
对undefined进行一元加操作,返回NaN;
对字符串进行一元加操作,有两种结果,如果字符串由纯数字构成的话,返回1,如果不是则返回NaN;
对对象进行一元加操作,也有两种结果,一是返回数字,二是返回NaN;操作过程中首先会调用valueOf方法,如果得不到数字结果,就调用toString方法,再对得到的字符串进行一元加操作;
摘抄
对数字进行一元加操作,结果返回数字本身,要注意对负数进行一元加操作结果还是负数啦,不要以为会得到整数;
对布尔类型进行一元加操作,true的话返回1,false返回0;
对null进行一元加操作,返0;
对undefined进行一元加操作,返回NaN;
对字符串进行一元加操作,有两种结果,如果字符串由纯数字构成的话,返回1,如果不是则返回NaN;
对对象进行一元加操作,也有两种结果,一是返回数字,二是返回NaN;操作过程中首先会调用valueOf方法,如果得不到数字结果,就调用toString方法,再对得到的字符串进行一元加操作;
属性访问 > 一元操作符 > 乘除 > 加减 > 比较 > 相等 > 与运算 > 或运算 > 三目运算 > 赋值运算
输出以下代码运行结果
1 + "1"
2 * "2"
[1, 2] + [2, 1]
"a" + + "b"
- 加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来 ==> "11"
- 乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值 ==> 4
- Javascript中所有对象基本都是先调用valueOf方法,如果不是数值,再调用toString方法。==> '1,2'+'2,1'==> '1,22,1'
- 一元操作符'+'的优先级大于加减运算,所以+"b"的结果为NaN,==》 “aNaN”
参考:一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值
+3 // 3
+"3" // 3
+true // 1
+false // 0
+null // 0
+function(val){ return val;} //NaN
很基础的题目,不过数组那个case有点不一样,它最后还会再执行join方法进行隐式转换
const arr = [1,2,3] const { toString, valueOf, join } = arr arr.toString = function(...args) { console.log('tostring'); return toString.call(arr, ...args) } arr.valueOf = function(...args) { console.log('valueOf'); return valueOf.call(arr, ...args) } arr.join = function(...args) { console.log('join'); return join.call(arr, ...args) } arr + [4,5,6]更多类型转换相关可见这里
其实是数组的toString方法里面调用的join方法,而不是本身就调用了join。在你的例子最下面加上console.log('test :>> ', arr.toString());可以看出join也打印了
1 - '1' = 0
1 / '1' = 1
1 + "1" // '11'
2 * "2" // 4
[1, 2] + [2, 1] // '1,22,1'
"a" + + "b" // 'aNaN'
1 + '1' :存在字符串时,+ 会进行字符串拼接
2 * "2" :乘法操作,"2" 会转化为数字,如果转换失败,会是 NaN
[1, 2] + [2, 1]:加法操作,[1, 2] 和 [2, 1] 是对象,会先调用 toString 方法,变成 "1,2" + "2,1"
"a" + + "b":可以分开来看,"a" + (+"b") => "a" + NaN => "aNaN"