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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。