JavaScript-数据类型知多少?

137 阅读2分钟

一、数据类型概念

基本数据类型

  • undefined
  • Null
  • Boolean
  • String
  • Number
  • Symbol
  • BigInt 引用数据类型
  • Object(Array、Regexp、Date、Math、Function) 重点: JavaScript的数据类型在初始化之后会放在不同的内存中,因此上面的数据类型可以按照两类来存储
  1. 基础数据类型存储在栈内存中,被引用或者被拷贝的时候会创建一个完全相等的变量;
  2. 引用数据类型存储在堆内存中,存储的是地址,可以有多个引用指向同一个地址;

二、数据类型检测

  1. typeof
    typeof 1                  // 'number'
    typeof '1'                // 'string'
    typeof undefined          // 'undefined'
    typeof                    // 'boolean'
    tyoeof Symbol()           // 'symbol'
    typeof null               // 'object'
    typeof []                 // 'object'
    typeof {}.                // 'object'
    typeof console            // 'object'
    typeof console.log.       // 'function'
    
    注意:
  1. typeof null 返回的结果是'object', 不代表null就是引用的数据类型,并且null本身也不是一个对象,因此这其实是一个有问题的结果,如果要想判断是否为null 直接 '=== null' 来判断.
  2. 引用类型用tyoeof来判断,出了function会返回 ‘function’ 之外,其余的都返回 ‘object’
  1. instanceof
   let Car = function() {}
   let b = new Car()
   b instanceof Car     // true

手写实现一个instanceof 判断数据类型

function myInstanceof (left, right) {
    // 如果是基本数据类型,直接返回false
    if(typeof lett !== 'object' || left === null) {
        return false
    }
    let proto = Object.getPrototypeof(left)
    while(true) {
        if(proto === null) {
            return false
        }
        if(proto === right.prototype) {
            return true
        }
    }
}

重点:

  1. instancoof 可以准确的判断引用数据类型,但是不能判断基本数据类型
  2. typeof 可以判断基本数据类型, null 除外,但是判断不了除了方法外的引用数据类型
  1. Object.prototype.toString

toString()是Object的原型方法,调用这个方法,能统一返回格式为'[Object Xxx]'的字符串,其中 ‘Xxx’ 就是对象的类型,对于Object,直接调用toString() 就能返回[Object Object];对于其他的对象,则需要通过call来调用,才能返回正确的结果

Object.prototype.toString({})                   // '[Object Object]'
Object.prototype.toString.call({})              // '[Object Object]'
Object.prototype.toString.call(1)               // '[Object Number]'
Object.prototype.toString.call('1')             // '[Object String]'
Object.prototype.toString.call(true)            // '[Object Boolean]'
Object.prototype.toString.call(function(){})    // '[Object Function]'
Object.prototype.toString.call(null)            // '[Object Null]'
Object.prototype.toString.call(undefined)       // '[Object Undefined]'
Object.prototype.toString.call(/123/g)          // '[Object RegExp]'
Object.prototype.toString.call(new Date())      // '[Object Date]'
Object.prototype.toString.call([])              // '[Object Array]'
Object.prototype.toString.call(document)        // '[Object HTMLDocument]'
Object.prototype.toString.call(widow)           // '[Object Window]'

手写通用的判断数据类型的方法

function getType(obj) {
    let type = typeof obj
    if(type !== 'object') {
        return type
    }
    return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1')
}

三、数据类型的转换方式

强制类型转换

Number()、parseInt()、parseFloat()、toString()、String()、Boolean()

隐式类型转换

凡是通过逻辑运算符(& || !)、 运算符 (+ - * /)、关系操作符(> < <= >=)、相等运算符(==)、或者if/while条件的操作,若是遇到两个数据类型不一样的情况下,都会存在隐式类型的转换。