说说js中的数据类型,以及如何存储

这个是js考察中一般会最先问到的题,这道题一定要答得顺畅,否则会影响你接下来和面试官的问答过程

基本数据类型和引用数据类型,基本数据类型包括:Undefined,Null, String,Number,Boolean,Symbol,其中Symbol是ES6新增的,引用类型统称为Object,细分的话,分为5个:Object,Array,Date,RegExp ,Function

基本数据类型和引用类型的区别:

基本数据类型和引用数据类型存储在内存中的位置不同,基本数据类型存储在栈中,引用类型的对象存储于堆中,

堆栈池存储

栈:存放变量

堆:存放复杂对象

池:存放常量

栈和堆是两种基本的数据结构,Stack在内存中自动分配内存空间,Heap在内存中动态分配内存空间,不一定会释放,一般在项目手动设置为null的原因,减少无用内存消耗

var a = 10
var b = a
b = 30
console.log(a)  //10
console.log(b)  //30

引用数据类型存放在堆内存中,每个对象在堆内存中有一个引用地址,栈中保存的就是这个对象在堆内存中的引用地址,

比方说每个房间都有房间号,房间号可以快速查找到保存在堆内存中的对象

var obj1 = new Object()
var obj2 = obj1
obj2.name = 'kobe'
console.log(obj1.name)  //kobe

面试题:输出下面的结果

let a = {n:1}
let b = a
a.x = a = {n:2}
console.log(a.x)  
console.log(b.x)

第一个输出是undefined

第二个输出是{n:2}

对于连续赋值语句来说,执行顺序是从右到左,但是 . 的优先级要高于 = ,所以a.先执行,

在这里插入图片描述

执行a = {n:2}时,会在堆栈中开辟一个新的内存,
在这里插入图片描述

a.x = a,对象{n:1,x:undefined}由于一直有一个b的指向,所以不会被JS的垃圾回收机制给回收,赋值后对象变为了{n:1,x:{n:2}}

在这里插入图片描述

类型转换

分为显示类型转换和隐式类型转换,每种转换又分为原始类型转换和对象类型转换

老生常谈的一道题0.1+0.2!=0.3

在js中0.1+0.2结果不是0.3,而是0.30000000000000004,

计算机的信息全部转化为二进制进行存储的,储的数字转为2进制后的有效数字大于52位,就会出现精度丢失的问题

js采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失

面试官:0.1 不等于 0.1 了,那为什么我在控制台上输出 console.log(0.1) 还等于 0.1 呢?

输入内容进行转换的时候,二进制转换成十进制,然后十进制转换成字符串,在这个过程中发生了取近似值,所以打印出来的是一个近似值,

数字类型转换

1.Number

将引用类型转化为字符串,首先将它基于toString方法转化为字符串,然后将字符串转化为数字

console.log(Number(10))             //10
console.log(Number('10'))           //10
console.log(Number(null))           //0
console.log(Number(''))             //0
console.log(Number(true))           //1
console.log(Number(false))          //0
console.log(Number([]))             //0
console.log(Number([1,2]))          //NaN
console.log(Number('10a'))          //NaN
console.log(Number('undefined'))    //NaN

2.parseInt()/parseFloat()

这个方法对于字符串来说,从左到右依次查找有效的数字字符,直到遇到非有效数字字符,停止查找,不管后面是否还有数字,都不在进行查找,

let str = '111.2a'
console.log(parseInt(str))          //111
console.log(parseFloat(str))        //111.2
console.log(parseInt(true))         //NaN
console.log(parseFloat(true))       //NaN

isNaN判断数据类型:

如果当前是数字类型,则返回false,否则返回true

console.log(isNaN(111))             //false
console.log(isNaN('111'))           //false
console.log(isNaN(undefined+1))     //true

面试题

var str1 = 'abc123';
var num = parseInt(str);
if(num == NaN){
    alert(NaN);
}else if(num == 123){
    alert(123);
}else if(typeof num == 'number'){
    alert('number');
}else{
    alert('str');
}

num得到是一个NaN,NaN是数字类型,所以输出为Number

字符串类型转换

转换字符串类型会默认调用toString()方法,

var a = null
var b = undefined
console.log(a.toString())  //(报错)
console.log(b.toString())  //(报错)
console.log(String(true))	//true
console.log(String(null))	//null
console.log(String(undefined))  //undefined
console.log(String([1,2,3]))   //1,2,3
console.log(String({}))		//[object Object]

布尔类型转换

Boolean('') // false
Boolean(undefined) // false
Boolean(null) // false
Boolean(NaN) // false
Boolean(false) // false
Boolean(0) // false
Boolean({}) // true
Boolean([]) // true

数据类型检测

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call()

1.typeof

除了null以及Object类型不能准确判断,其他的数据类型都可以

typeof undefined // 'undefined'
typeof '10' // 'String'
typeof 10 // 'Number'
typeof false // 'Boolean'
typeof Symbol() // 'Symbol'
typeof Function // ‘function'
typeof null // ‘Object’
typeof [] // 'Object'
typeof {} // 'Object'
面试官:为什么typeof null是Object?

不同对象在底层原理的存储是二进制表示,在js中,如果二进制的前三位都是0的话,系统会判定为是Object类型,null的存储二进制是000,前三位都是0

2.instanceof

instanceof测试一个对象在其原型链中是否存在一个构造函数的prototype属性,用instanceof判断某个对象是不是另一个对象的实例

function Fn() {}
var f1 = new Fn()
console.log(f1 instanceof Fn)

在这里插入图片描述

3.constructor

console.log(fn.constructor.name) // Function
console.log(date.constructor.name)// Date
console.log(arr.constructor.name) // Array
console.log(reg.constructor.name) // RegExp

4.Object.prototype.toString.call()

最好的基本类型检测方式

// 判断基本类型
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(“abc”);// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"

function Fn() {}
var f1 = new Fn()
console.log(f1 instanceof Fn)

// 判断引用类型
function fn () {
    console.log('kobe')
}
var data = new Date()
var arr = [1,2,3]
var reg =  /[hbc]at/gi
console.log(Object.prototype.toString.call(fn))
console.log(Object.prototype.toString.call(data))
console.log(Object.prototype.toString.call(arr))
console.log(Object.prototype.toString.call(reg))

缺陷的话就是不能区分是谁的实例

null和undefined的区别?

null表示‘无’的对象,undefined表示‘无’的原始值

用法上面有区别

null
  • 作为函数的参数,表示该函数的参数不是对象
  • 作为对象原型链的终点
undefined
  • 变量被声明了,但是没有赋值就是undefined
  • 调用函数时应提供的参数没有提供,该参数等于undefined
  • 对象没有赋值的属性,该属性的值为undefined
  • 函数没有返回值的时候,默认是undefined

今天距2021年还有36天,希望大家一起在2020年末继续努力,冲冲冲!
明年一起收割offer

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值