每天一道面试题(2) - 你真的了解JS的数据类型吗?

你了解JS的数据类型吗? 这应该是js中最基础的一个问题了, 可是就从这最基础的一个问题, 你能挖掘多深呢?

本文将从以下几个方面进行梳理

js的基本数据类型有哪些

1.js基本数据类型有六种

  • undefined
  • Boolean
  • Number
  • String
  • BigInt(可以用任意精度表示整数, 安全的存储和操作大整数)
  • Symbol

2.null是一种特殊的数据类型, 在被typeof判断的时候会被判断成object

3.引用数据类型
包括对象, 数组, 函数等

基本数据类型和引用数据类型的区别是什么

  • 基本数据类型存放在栈内存中, 而引用数据类型存放在堆内存中
  • 基本数据类型复制可以直接拿到值本身, 而引用类型复制时只能拿到数据的内存地址, 因此需要进行深拷贝
  • 判断类型时, 基本类型使用typeof即可判断,但是typeof检测引用类型时只会判断出是object, 不能得到具体的类型. 所以引用类型必须要通过instanceof判断或者原型的方法判断

判断数据类型的方法

判断基本数据类型

undefinedtypeof instance === "undefined"
Boolean:typeof instance === "boolean"
Number:typeof instance === "number"
String:typeof instance === "string
BigInt:typeof instance === "bigint"
Symbol :typeof instance === "symbol"

对于复杂类型

var a = [1,2,3];
var b = new Date();
var c = function(){}
//结果如下
typeof a === 'object' //true
typeof b === 'object' //true
typeof c === 'function' //true

无法判断Object类型中的具体类型, 所以这时需要用到instanceof

判断Object类型

顾名思义, instanceof的原理就是判断当前元素是否是某构造函数的实例

a instanceof Array //true
b instanceof Date //true
c instanceof Function //true

a instanceof Object //true
b instanceof Object //true
c instanceof Object //true

为什么a instanceof Object为真呢?

因为所有函数包括Array,Date等构造函数, 都是Object的实例

其实也可以理解为, Array等构造函数的原型肯定是一个对象, 那对象的构造函数肯定是Object;

也可以理解
Array.prototype.__proto__ = Object.prototype

还有一些特殊情况

Object instanceof Function  // true
Function instanceof Object //true

可以理解为是Object本身就是一个构造函数, 所以肯定是Function的实例

Function的原型又是一个对象, 所以反之也成立

通过Object.prototype判断

Object.prototype.toString.call(a) // 'object Array'
Object.prototype.toString.call(b) // 'object Date'
Object.prototype.toString.call(c) // 'object Function'
Object.prototype.toString.call(null) // 'object Null' //特殊记忆

值得一提的是,就是toString方法,下面来看

toString方法

var num = 123
num.toString() // '123'

var str = 'hello'
str.toString() // 'hello'

var bool = false
bool.toString() // 'false'

var arr = [1, 2, 3]
arr.toString()  // '1,2,3'

var obj = {lang:'zh'}
obj.toString()  // '[object Object]'

var fn = function(){}
fn.toString()  // 'function(){}'

null.toString()  // Cannot read property 'toString' of null

undefined.toString() // Cannot read property 'toString' of undefined

平时我们用到的toString方法是将其他类型转换为字符串, 下面看一下对象Object.prototype上的toString方法

Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"

对象上的toString方法输出的是一个函数, 而原型上的toString方法输出的是数据类型

其实在我们熟知的Array Function Object等构造函数上都有定义toString方法

不同数据类型之间的转换

既然toString是将其他类型转换为字符串类型, 那么不同数据类型之间怎么转换呢

我们进行计算或转换的数据类型通常是字符串和数组, 数字之间的转换

字符串和数字的转换

字符串转数字, 有parseInt, parseFloat,Number三种, 具体区别不多说

let a = '123'
parseInt(a) //123
parseFloat(a) //123
Number(a) //123

let b = '123.4'
parseInt(b) //123
parseFloat(b) //123.4
Number(b) //123.4

let c = '123.4c'
parseInt(c) //123
parseFloat(c) //123.4
Number(c) //NaN

数字转字符串

let a = 1
let b = a+'' //'1'
let c = a.toString() //'1'
字符串和数组的转换

字符串转数组

let a = '123'
let b = a.split('') // ['1','2','3']

数组转字符串

let a = ['1','2','3']
let b = a.join('') //'123'

堆和栈的区别

js中基本数据类型存储在栈内存中, 引用类型存储在堆内存中, 那么堆和栈的主要区别有哪些呢?

主要区别有:

  • 在c++中栈内存是系统自行分配的; 堆内存是手动申请的
  • 栈内存是一段连续的有限空间; 堆内存是不连续的随机的空间(引用类型所占内存不固定)
  • 栈的存取速度比较快, 使用完成后立即释放,会被垃圾回收; 堆内存存取速度比较慢, 但是申请使用比较灵活; 但是要所有的引用都销毁之后才会被垃圾回收

null存在栈内存中

闭包中的基本数据类型变量是保存在堆内存里的,当函数执行完弹出调用栈后,返回一个内部函数的一个引用,这时候函数的变量就会转移到堆上,因此内部函数依然能访问到上一层函数的变量。

题外话: 原本以为每天写一篇小面试题还挺容易的, 没想到想写的详细还挺费时间的, 不知道自己能坚持几天, 也不知道有没有人看

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值