使用+运算符
-
当有object时候,使用toString()的返回值,如果返回值不是一个基本类型的值,将报错
//toString的对象 var obj2 = { toString:function(){ return 'a' } } console.log('2'+obj2) //输出结果2a //常规对象 var obj1 = { a:1, b:2 } console.log('2'+obj1); //输出结果 2[object Object] -
有String类型,+效果是拼接字符串,使用String()转成字符串
'2' + 1 // '21' '2' + true // "2true" '2' + false // "2false" '2' + undefined // "2undefined" '2' + null // "2null" '2'+ {toString(){return '[object Object]'}} //"2[object Object]" '2' + Date.now() //"221601086218979" -
无object,无string,优先Number(),其次转Boolean()
2+2 //4 2+true //3 2+false //2 true + 0 // 1 true + true // 2 true + false //1 false + null //0 true + null //1
减乘除运算符(转成数值)
'5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
null + 1 // 1
undefined + 1 // NaN
//一元运算符(注意点)
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
null与数字加减运算时会转为0,undefined会转为NaN,Symbol类型相加会报错
比较运算符
相等运算符(==和!=)使用抽象相等比较算法比较两个操作数。可以大致概括如下:
- 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true。
- 如果一个操作数是null,另一个操作数是undefined,则返回true。
- 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
- 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
- 如果操作数之一是Boolean,则将布尔操作数转换为1或0。
- 如果是true,则转换为1。
- 如果是 false,则转换为0。
- 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。
- 如果操作数具有相同的类型,则将它们进行如下比较:
- String:true仅当两个操作数具有相同顺序的相同字符时才返回。
- Number:true仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false。
- Boolean:true仅当操作数为两个true或两个false时才返回。
- 此运算符与严格等于(===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同
1 == 2 //false
var obj1 = {
valueOf:function(){
return '1'
}
}
1 == obj1 //true
//obj1转为原始值,调用obj1.valueOf()
//返回原始值'1'
//'1'toNumber得到 1 然后比较 1 == 1
[] == ![] //true
//[]作为对象ToPrimitive得到 ''
//![]作为boolean转换得到0
//'' == 0
//转换为 0==0 //true
什么时候进行布尔转换
- 布尔比较时
if(obj) , while(obj)等判断时或者 三元运算符只能够包含布尔值
js中的数据类型判断
三种方式,分别为 typeof、instanceof 和Object.prototype.toString()
- typeof
typeof 'seymoe' // 'string'
typeof true // 'boolean'
typeof 10 // 'number'
typeof Symbol() // 'symbol'
typeof null // 'object' 无法判定是否为 null
typeof undefined // 'undefined'
typeof {} // 'object'
typeof [] // 'object'
typeof(() => {}) // 'function'
需要注意的是,对于
typeof, 可以正确判断除了null之外的所有基本类型 而对于引用类型,除了函数外其他都会被判断为object。
- instanceof
通过 instanceof 操作符也可以对对象类型进行判定,其原理就是测试构造函数的prototype 是否出现在被检测对象的原型链上。
[] instanceof Array // true
({}) instanceof Object // true
(()=>{}) instanceof Function // true
let arr = []
let obj = {}
arr instanceof Array // true
arr instanceof Object // true
obj instanceof Object // true
instanceof无法判断基本类型,但可以正确判断引用类型, 数组会认为是object的实例,因为数组是object的子类型即
Array.prototype__proto__===Object.prototype
- Object.prototype.toString()
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(() => {}) // '[object Function]'
Object.prototype.toString.call('seymoe') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(Symbol()) // '[object Symbol]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call(Math) // '[object Math]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new WeakSet()) // '[object WeakSet]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
toString()和String()的区别
- toString()
toString()括号中可以写数字,代表进制 二进制:.toString(2);
八进制:.toString(8);
十进制:.toString(10);
十六进制:.toString(16);
- String()
String()可以将null和undefined转换为字符串,但是没法转进制字符串
console.log(String(null));// null
console.log(String(undefined));// undefined