加号运算符
3 + 4 + '5' // '345'
6 + '7'+ 8 // '678'
[] + {} // '[object Object]'
{} + [] // 0
0 + [] // '0'
0 + {} // '0[object Object]'
1 + false // 1
1 + undefined// NaN
1 + null // 1
1 + {} // '1[object Object]'
1+ [] // '1'
1 + undefined + '' // 'NaN'
1 + undefined + 12 // NaN
1 + undefined + '12' // 'NaN12'
1 + [12] // '112'
1 + [1,2,3] // '11,2,3'
undefined + '' // 'undefined'
null + '' // 'null'
false + '' // 'false'
{} + '' // 0
[] + '' // ''
!!NaN + 1 // 1
[][0] + 1 // NaN
+号运算逻辑
- 相加运算符(+)为两种不同的运算重载:
- 1, 数字加法 2,字符串连接
- 如果操作数中有一方为字符串,则该运算符将两个操作数连接成一个字符串。
- 将两个操作数强制装换为原始值然后检查两个操作数的类型
- 如果一方是字符串,另一方也会被转换成字符串,两个字符串连接
- 如果双方都是BigInt 则执行BigInt 方法,如果一方是,一方不是BigInt 会抛出TypeError
- 否则 双方都会转换为数字,执行数字加法
- 字符串连接经常认为等价于 模板字符串或者 String.prototype.concat() 但是并非如此.加法强制将表达式转换为原始值,
- 它优先调用valueOf() 另一方面 模板字符串和concat()则强制表达式转为字符串优先调用toString,默认优先调用
- Symbol.toPrimitive 是内置的 symbol 属性,其指定了一种接受首选类型并返回对象原始值的表示的方法。它被所有的强类型转换制算法优先调用。
特殊的
{} + '' // 0
// {} 在前被认为是一个代码块执行,但是代码块里无代码
// 等同于 +'' 结果 0
[][0] + 1 // NaN
// 第二个[]是一个获取[]中下标第0个的数据
// 获取到的数据 undefined + 1 //NaN
!!NaN + 1 // 1
// !!NaN 强制转换为 Boolean 基础类型
// false + 1
// false 隐式转换为数字 0
// 0 + 1 //1
新增类型转换面试题
true + false // 1
/*
=> 1 + 0
=> 1
*/
12 / "6" //2
/*
=> 12 / 6
=> 2
*/
"number" + 15 + 3 //"number153"
/*
=> "number15" + 3
=> "number153"
*/
15 + 3 + "number"
/*
=> 18 + "number"
=> "18number"
*/
[1] > null // true
/*
=> '1' > 0
=> 1 > 0
=> true
*/
"foo" + + "bar"
/*
=> "foo" + (+"bar")
=> "foo" + NaN
=> "fooNaN"
*/
"true" == true
/*
=> "true" 转数字 NaN
=> NaN == true
=> false
*/
null == ""
/*
=> null 只等于自身或者 undefined
=> false
*/
!!"false" == !!"true"
/*
=> !!"false" 转boolean
=> !"false" 转boolean "false" 为true ==> !true 为false ==> !!true 为true
=> true == true
=> true
*/
["x"] == "x"
/*
=> ["x"] 转原始类型 ["x"].toString() ===> 'x'
=> 'x' == 'x'
=> true
*/
[] + null + 1
/*
=> '' + null + 1
=> 'null' + 1
=> 'null1'
*/
[1,2,3] == [1,2,3]
/*
=> 类型相同,比较值,由于是引用类型比较内存地址
=> false
*/
{} + [] + {} + [1]
/*
=> (代码块)(+[])+{}+[!]
=> +[] + {} + [1]
=> 0 + {} + [1]
=> 0 + '[object Object]' + '1'
=> '0[object Object]1'
*/
! + [] + [] + ![]
/* 一元运算符优先执行,+[] 转为 number 类型 0,![] 转为 boolean 型 false。
=> !(+[]) + [] + (![])
=> !0 + [] + false
=> true + [] + false
=> true + '' + false
=> 'truefalse'
*/
new Date(0) - 0
/* '-' 运算符执行 number 类型隐式转换对于 Date 型的值,Date.valueOf() 返回到毫秒的时间戳。
=> 0 - 0
=> 0
*/
new Date(0) + 0
/* '+' 运算符触发默认转换,因此使用 toString() 方法,而不是 valueOf()。
=> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0
=> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0'
*/