<javascript> 四则运算中的强制转换 -- 加法"+"

219 阅读2分钟

最近重温大神yck 的大作<前端面试之道>,受益良多。关于四则运算中的类型转换部分,加法部分还是有点不明白,于是自己尝试着重新总结一下规律。

四则运算中的加法之所以诡异,在于“+”什么时候看成“加号”,什么时候看成“连字符”?以下是我自己总结的规律:

------------------------ 我是废话分割符 --------------------------

- 规律:

  1. 当“+”两边都是 number 或者 boolean,“+” 视作“加号”
  2. 当“+”两边都是[object Object], 返回 NaN (强制转换为数字)
  3. 不符合以上两种情况, 转换为string

- 代码:

// 1. 当“+”两边都是 number 或者 boolean,“+” 视作“加号”
console.log('1 + 2 =', 1 + 2);  // 3
console.log('NaN + 2 =', NaN + 2); // NaN// 1. 当“+”两边都是 number 或者 boolean,“+” 视作“加号”
console.log('1 + 2 =', 1 + 2);  // 3
console.log('NaN + 2 =', NaN + 2); // NaN
console.log('NaN + NaN =', NaN + NaN); // NaN
console.log('true + true =',true + true); // 2
console.log('false + false =',false + false); // 0
console.log('true + 2 =',true + 2); // 3
console.log('false + 2 =',false + 2); // 2

// 2. 当“+”两边都是[object Object], 返回 NaN (强制转换为数字)
console.log({} + {}); // NaN

// 3. 不符合以上两种情况, 转换为string 
// eg.
//     3.1 一方为string
console.log('1 + \'2\' =', 1 + '2'); // '12'
console.log('true + \'2\' =', true + '2'); // true2
console.log('[] + \'2\' =', [] + '2'); // '2'
console.log('{} + \'2\' =', {} + '2'); // '[object Object]2'
console.log('function fn() { } + \'2\' =', function fn() { } + '2'); // 'function fn(){}2' 

//    3.2 一方为 number or boolean
console.log('[] + 0 =', [] + 0); // '0'
console.log('[] + 2 =', [] + 2); // '2'
console.log('[1] + 2 =', [1] + 2); // '12'
console.log('[1,2,3] + 2 =', [1, 2, 3] + 2); // '1,2,32'
console.log('[1,2,3,] + 2 =', [1, 2, 3,] + 2); // '1,2,32'
console.log('{} + 2 =', {} + 2); // '[object Object]2'
console.log('[] + true =', [] + true); // 'true'
console.log('{} + true =', {} + true); // '[object Object]true'

//    3.3 双方都不是string 
console.log('[]+[] =', [] + []);  // ''
console.log('[]+{} =', [] + {});  // '[object Object]'
console.log('NaN + {} =', NaN + {});  // 'NaN[object Object]'
console.log('function fn() { } + {} =', function fn() { } + {}); // 'function fn(){}[object Object]' 
console.log('function fn() { } + [] =', function fn() { } + []); // 'function fn(){}' 


console.log('NaN + NaN =', NaN + NaN); // NaN
console.log('true + true =',true + true); // truetrue
console.log('false + false =',false + false); // falsefalse
console.log('true + 2 =',true + 2); // 3
console.log('false + 2 =',false + 2); // 2

// 2. 当“+”两边都是[object Object], 返回 NaN (强制转换为数字)
console.log({} + {}); // NaN

// 3. 不符合以上两种情况, 转换为string 
// eg.
//     3.1 一方为string
console.log('1 + \'2\' =', 1 + '2'); // '12'
console.log('true + \'2\' =', true + '2'); // true2
console.log('[] + \'2\' =', [] + '2'); // '2'
console.log('{} + \'2\' =', {} + '2'); // '[object Object]2'
console.log('function fn() { } + \'2\' =', function fn() { } + '2'); // 'function fn(){}2' 

//    3.2 一方为 number or boolean
console.log('[] + 0 =', [] + 0); // '0'
console.log('[] + 2 =', [] + 2); // '2'
console.log('[1] + 2 =', [1] + 2); // '12'
console.log('[1,2,3] + 2 =', [1, 2, 3] + 2); // '1,2,32'
console.log('[1,2,3,] + 2 =', [1, 2, 3,] + 2); // '1,2,32'
console.log('{} + 2 =', {} + 2); // '[object Object]2'
console.log('[] + true =', [] + true); // 'true'
console.log('{} + true =', {} + true); // '[object Object]true'

//    3.3 双方都不是string 
console.log('[]+[] =', [] + []);  // ''
console.log('[]+{} =', [] + {});  // '[object Object]'
console.log('NaN + {} =', NaN + {});  // 'NaN[object Object]'
console.log('function fn() { } + {} =', function fn() { } + {}); // 'function fn(){}[object Object]' 
console.log('function fn() { } + [] =', function fn() { } + []); // 'function fn(){}' 


以上在 1)browser 和 2)save as "calculation.js", and then node calculation 验证过。直接在node 环境跑里有点诡异,我还在晕晕晕 @.@

PS Z:\> node
> {} + 2
2
> console.log({} + 2);
[object Object]2
undefined
> let a = {} + 2; a
'[object Object]2'
>

感谢大佬提醒,给忘了{} 还能表示block,加个括号,满世界都清净了

> ({} + 2)
'[object Object]2'