js类型转换与数据类型判断

206 阅读4分钟

使用+运算符

  • 当有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与数字加减运算时会转为0undefined会转为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