front-end-pigs / blog

博客
2 stars 0 forks source link

js类型隐式转换坑点 #3

Open jangdelong opened 5 years ago

jangdelong commented 5 years ago

js类型隐式转换坑点

2019-06-23更新

jangdelong commented 5 years ago

一、字符连接符【转字符串】

即字符串连接操作,一般以“+”号来进行连接,在隐式转换时容易跟算术运算符的“+”号混淆,算术运算符“+”在后面的节点中会具体再介绍,本节点主要是列举一些常见的不同类型数据隐式转换成字符串连接的例子。

  1. 字符串类型+数字类型->(String(字符串) + String(数字))
console.log('abc' + 1);  // 输出:'abc1'
console.log('abc' + 234); // 输出:'abc234' 
  1. 字符串类型+布尔类型->(String(字符串) + String(布尔值))
console.log('abc' + true); // 输出:'abctrue'
console.log('abc' + false); // 输出:'abcfalse'
  1. 字符串类型+Undefined类型->(String(字符串) + String(undefined))
console.log('abc' + undefined); // 输出:'abcundefined'
  1. 字符串类型+Null类型-> (String(字符串) + String(null))
console.log('abc' + null); 输出: 'abcnull'

小结:1-4你会发现一个规律,只要一边为字符串类型,结果都会转成字符串类型,如果说这个比较好理解,那么接下来的可能会稍微有点难理解,就是两边都不是字符串类型的数据,但结果会转成字符串类型。

  1. 数组类型 + 数组类型->(String(数组) + String(数组))
console.log([] + []); // 输出:'' ,即空字符串
console.log([ 1, 2, 3, 4 ] + [ 5, 6, 777 ]); // 输出:'1,2,3,45,6,777'
  1. 对象 + 对象->(String(对象) + String(对象))
console.log({} + {}); // 输出:'[object Object][object Object]'
console.log({ name: 'Jelon' } + { name: 'Huozhi' }); // 输出:'[object Object][object Object]'
console.log({} + { name: 'Jelon' }); // 输出:'[object Object][object Object]'
  1. 数组 + 对象-> (String(数组) + String(对象))
console.log([] + { name:  'Jelon' }); // 输出:'[object Object]'
console.log([ 1, 2, 3 ] + { name: 'Jelon' }); // 输出:'1,2,3[object Object]'
  1. 数组 + Null类型(也会转成字符串连接)
console.log([] + null); // 输出:'null'
console.log([ 1, 2, 3 ] + null); // 输出:1,2,3null
  1. Null类型 + 对象(注意,顺序不能变,必须null在第一位,因为反过来就变成算术运算了,算术运算章节再详讲)
console.log(null + {}); // 输出:'null[object Object]'
console.log(null + { name: 'Jelon' }); // 输出:'null[object Object]'
  1. Undefined类型 + 对象(注意,顺序不能变,必须undefined在第一位,因为反过来也是变成算术运算了,算术运算章节在详讲)
console.log(undefined + {}); // 输出:'undefined[object Object]'
console.log(undefined + { name: 'Jelon' }); // 输出:'undefined[object Object]'
  1. Undefined类型 + 数组(顺序可改变)
console.log(undefined + [1, 2, 3]); // 输出:'undefined1,2,3'
console.log([1, 2, 3] + undefined); // 输出:'1,2,3undefined'
  1. 数字类型/布尔类型 + 数组->(String(数字/布尔) + String(数组))
console.log(1 + [ 2, 3 ]); // 输出:'12,3'
console.log([] + 123); // 输出:'123'
console.log(true + []); // 输出:'true'
  1. 数字类型/布尔类型 + 对象(注意,顺序不可逆,数字类型/布尔类型必须在第一位,否则会转换为算术运算)
console.log(1 + { name: 'Jelon'  }); // 输出:'1[object Object]'
console.log(123 + {}); // 输出:'123[object Object]'
console.log(true + {}); // 输出:'true[object Object]'

小结:5-13你会发现一个规律,那就是任意一个数据类型 + 数组/对象,结果都会隐式转换为字符串类型;对于任意数据类型 + 对象,顺序是不可逆。

jangdelong commented 5 years ago

二、算术运算符“+”【转数字类型】

  1. 数字类型 + 布尔类型/Null类型->(Number(数字) + Number(布尔值/null)),顺序可逆
console.log(1 + true); // 输出:2
console.log(false + 1); // 输出:2
console.log(1 + null); // 输出:1
  1. 对象 + 数字类型/Null类型(注意,顺序不可逆)
console.log({} + 4); // 输出:4
console.log({ name: 'Jelon' } + 4); // 输出:4
console.log({} + null); // 输出:0
  1. 布尔类型 + 布尔类型->(Number(布尔值) + Number(布尔值))
console.log(true + true); // 输出:2
console.log(false + false); // 输出:0
  1. 布尔类型 + Null类型->(Number(布尔值) + Number(null))
console.log(true + null); // 输出:1
console.log(null + false); // 输出:0
jangdelong commented 5 years ago

三、其他运算符

  1. 按非运算(~)-> 数字类型
console.log(~undefined); // 输出: -1
console.log(~~undefined); // 输出: 0

console.log(~false); // 输出: -1
console.log(~~false); // 输出: 0

console.log(~true); // 输出:-2
console.log(~~true); // 输出:1

console.log(~'10'); // 输出:-11
console.log(~~'10'); // 输出:10