js中有哪些数据类型及区别

基本数据类型

  • string / number / boolean / undefined / null / symbol(代表创建之后独一无二,且不可变的数据类型)

引用数据类型

  • Object

基本数据类型与引用数据类型的区别

  • 声明变量时存储分配不同,基本数据类型存储在栈中,引用数据类型存储在堆中。
  • 不同的内存分配机制导致访问机制也不同。基本类型可以直接被访问的,引用数据要先访问存储在栈中的引用地址,再根据引用地址找到堆中的实体。(不可以直接访问堆内存的位置以及直接操作堆内存空间,只能操作对象在栈内存中的引用地址)
  • 赋值变量时不同,基本数据类型会将原始值的副本赋值给新的变量(传值),而引用类型是将引用类型的地址复制给新的变量(传址)

    面试真题

null与undefined 的区别
* null 表示 “没有对象”,该处不应该有值
* undefined 表示 “缺少值”,该处应该有值,但实际上缺少
* 转为数值不同,null 转成数字类型为 0, undefined 转成数字类型为 NAN
* null表示 “没有对象”,该处不应该有值

null与undefined 使用场景
* null
    1、作为函数的参数,表示该函数的参数不是对象
    2、作为对象原型链的终点 (Object.getPrototypeOf(Object.prototype) 值为null)
* undefined
    1、变量被声明但是没有被赋值
    2、调用函数时,本应提供的参数没有提供,该参数就等于undefined
    3、对象没有被赋值的属性,该属性的值为undefined
    4、函数没有返回值时,默认返回undefeined
    
    console.log(Number(null))
    console.log(Number(undefined))
    console.log(Object.getPrototypeOf(Object.prototype))
    

js数据类型检测的方法
* typeof(检测数据类型的运算符)
* typeof null的结果为Object本质上是一个bug。在 javascript 的最初版本中,使用的 32位系统,js为了性能优化,使用低位来存储变量的类型信息。 在判断数据类型时,是根据机器码低位标识来判断的,而null的机器码标识为全0,而对象的机器码低位标识为000。所以typeof null的结果被误判为Object

    console.log('数值',typeof 7) // 数值 number
    console.log('字符串',typeof '77') // 字符串 string
    console.log('布尔值',typeof true) //布尔值 boolean
    console.log('数组',typeof []) //数组 object
    console.log('函数',typeof function(){}) //函数 function
    console.log('对象',typeof {}) //对象 object
    console.log('undefined',typeof undefined) //undefined undefined
    console.log('null',typeof null) //null object  

* instanceof (检测某一实例是否属于这个类)
* 可以正确判断对象的类型,不可以判断基本数据类型
* 内部运行机制:判断在它的原型链上能否找到这个类型的原型
* 注意:不可以用来检测null 、undefined 类型

    console.log('数值',7 instanceof Number) // 数值 false
    console.log('字符串','77' instanceof String) // 字符串 false
    console.log('布尔值', true instanceof Boolean) //布尔值 false
    console.log('数组', [] instanceof Array) //数组 true
    console.log('函数',function(){} instanceof Function) //函数 true
    console.log('对象', {} instanceof Object) //对象 true

* constructor(检测实例和类的关系,从而检测数据类型,引用原来构造该对象的函数)

    console.log('数值',(7).constructor === Number) // 数值 true
    console.log('字符串',('77').constructor ===  String) // 字符串 true
    console.log('布尔值', (true).constructor ===  Boolean) //布尔值 true
    console.log('数组', ([]).constructor ===  Array) //数组 true
    console.log('函数',(function(){}).constructor ===  Function) //函数 true
    console.log('对象', ({}).constructor ===  Object) //对象 true

* Object.prototype.toString.call()
* 为什么要用原型上的toString 方法: 因为数据都是由Object 实例创建而来,但是数据本身的toString方法会被重写,通过call复制原型上的方法即可准确无误的判断数据类型,朋友们,强烈推荐此方法!
    const typeOfStr = str=>Object.prototype.toString.call(str).slice(8,-1)
    console.log('数值',typeOfStr(7)) // 数值 Number
    console.log('字符串',typeOfStr("77")) // 字符串 String
    console.log('布尔值', typeOfStr(true)) //布尔值 Boolean
    console.log('数组', [], typeOfStr([])) //数组 Array
    console.log('函数',typeOfStr(function(){})) //函数 Function
    console.log('对象',typeOfStr({})) //对象 Object
    console.log('undefined',typeOfStr(undefined)) //undefined Undefined
    console.log('null',typeOfStr(null)) //null Null 
    

 

闭包

定义:1、函数中返回一个函数,2、函数声明的作用域和函数使用的作用域不同
用途:获取私有作用域的变量(此处timer为私有作用域变量,这些变量可以保存到内存中)
const debounce = (()=>{
    let timer = null;
    return (callback,time)=>{
        timer && clearTimeout(timer)
        timer = setTimeout(callback,time)
    }
})()
闭包的优缺点
  • 优点:避免全局变量的污染。变量长期储存在内存中(缓存变量)
  • 缺点:内存泄露(消耗),常驻内存,增加内存使用量

    面试真题

// 普通方式
var fnArr = [];
for(var i=0;i<10;i++){
    fnArr[i] = function(){
        return i
    }
}
console.log(i)  //结果为 10
console.log(fnArr[7]())  // 结果为 10
//闭包写法
var fnArr = [];
for(var i=0;i<10;i++){
    fnArr[i] = (function(){
        let j = i;
        return function(){
            return j
        }
    })()
}
console.log(i)  // 结果为10
console.log(fnArr[7]())  //结果为 7 

茴香
34 声望1 粉丝

好好学习,天天向上