前言
在JavaScript的世界里,数据类型是构建一切应用的基石。从简单的数字、字符串到复杂的对象、数组,每一种数据类型都承载着特定的使命,决定了数据的存储方式、操作逻辑与交互规则。本文将结合js底层v8运行逻辑,带你深入了解所有数据类型成为js“筑基高手“”。
JS数据类型
-基本类型(原始类型)
1.字符串类型(string) 字符串类型在js中通常扮演文本角色,就像写在纸条上的文字,可以是一句话、一个名字,内容固定且不可更改,只能用新纸条替换旧纸条。示例如下:
let str = 'hello world'//string 类型
let str2 = str+'js'//空格也是一个字符
let str2 = `${str} js`
console.log(str[5])
console.log(str.at(5))//与上一句等效
运行结果如下
由以上代码我们可知道,js的字符串类型可以用“+”实现拼接,提取则可用[]+i下标或者‘at[]’实现,切割则用js自带的slice方法,注意只取左边不取右边。
2.数字类型(number) 就像算盘上的算珠,用来表示数量、金额、年龄等,支持加减乘除各种数学运算。示例如下
let num =123//number 类型
let num2= num+0.1
console.log(num2)
console.log(num2.toString());//转换成字符串类型
console.log(num2+'5')//v8 引擎会自动将数字类型转换成字符串类型并拼接
console.log(9007199254740992+1)//算不出,因为超过最大安全整数范围 2^53 9007199254740992
需要注意其值包含包括整数、小数,还有特殊值NaN,还有转换成字符串方法.toString(),还有一点js让你大吃一惊的地方,在用数字加字符串时,v8 引擎会自动将数字类型转换成字符串类型并拼接,是不是觉得v8太不公平了,我也这么觉得,区别对待。
3.3. 布尔类型(boolean) 与你所接触过的编程语言一样,就像开关按钮,只有两种状态——「开」(true)或「关」(false),非黑即白,没有中间地带。
if(NaN){//boolean 布尔类型
console.log('true');
}
- 空类型(null)和bigint类型
let n=null//null类型
let b=123123123n//bigint 类型
bigint类型用于表示超出number范围的整数,在数字后面加n表示,比如9007199254740993n,解决了number最大安全整数的限制,而null类型就像一个空盒子,盒子是存在的,但里面什么都没有,是我们主动放进去的「空」。
5.未定义类型(undefined)
就像一块还没开垦的空地,我们知道这里应该有个位置,但还没有放置任何东西,甚至连空盒子都没有。 变量声明后未赋值,默认就是undefined。
let u=undefined+''
console.log(u)
6.symbol类型 symbol类型就像独一无二的指纹,每个symbol都是唯一的,哪怕看起来一样,也绝对不会冲突,用来做保密的标识。即使两个Symbol的值看起来一样,它们也不相等,主要用于对象的唯一属性名,避免属性冲突
let s=Symbol('hello');//Symbol('hello')代表hello是独一无二的值,无特殊含义
let p=Symbol('hello');
console.log(s==p);//故他们两个不相等
补充一个干货知识点:先看一段代码
let b=1;
let c='1'
console.log(b==c)//true,因为等号操作符两边会自动转换成数字类型
console.log(b===c)//false
console.log(b.toString()===c)//true
为什么第一个是true,第二个是false呢?这是因为等号操作符两边会自动转换成数字类型,从而将字符串1转换为数字一,而全等符号‘===’必须什么都相等,包括类型
-引用类型
- 对象类型(object)
- 数组类型(array)
- 函数类型(function) 4.date类型(date)
对象类型(object)
就像一个带标签的文件夹,里面可以放各种东西(属性),每个东西都有自己的名字(键),想找什么按标签找就行。用大括号包裹,是JS中最常用的复杂类型,支持动态添加、修改、删除属性。
var obj={
name:'张三',
age:18,
like:{
sport:'篮球',
two:{
sports:['篮球','足球']
}
}
}
obj.gender='男'
delete obj.age
console.log(obj)
数组类型(array)
就像一列火车车厢,每个车厢按顺序排列,有编号(索引),可以依次访问,也可以随时加车厢、减车厢。里面可以存放任意类型的数据,可通过索引访问和修改元素。日常开发中常用数组增删改查操作。
var arr=[1,2,3,4,5]
arr.push(4)//在数组末尾添加一个元素
arr.pop()//删除数组最后一个元素
arr.shift()//删除数组第一个元素
arr.unshift(0)//在数组开头添加一个元素
arr.splice(2,2)//删除数组中索引为2的元素,删除2个元素
arr.splice(2,0,6,7,8)//在数组中索引为2的位置插入6,7,8
arr[2]=9//将数组中索引为2的元素赋值为9
console.log(arr)
具体操作看注释
函数类型(function)
就像一台榨汁机,你把水果(参数)放进去,它按照设定的程序(函数体)工作,最后吐出果汁(返回值)。用于封装逻辑、实现复用,也是一种特殊的对象。
function fn() {
console.log("执行函数");
}
console.log(fn);
date类型(date)
就像一本万年历,可以记录具体的年月日时分秒,帮我们计算时间差、格式化日期等。用于处理日期和时间,可创建日期对象、获取当前时间、格式化时间等,比如Date() 可获取当前系统时间。
数据执行与v8调用栈和堆的关系
- 创建一个调用栈(用来存储预编译的过程)
- 在调用栈中,存入xx执行上下文
- 执行代码,将原始值变存入栈中,如果遇到引用类型的值,则将值存入堆空间并生成一个引用地址,将引用地址存入栈中,这样设计好处,即既保证了栈空间的效率,又保证了引用类型的值的效率,不影响v8执行效率,又不会爆栈。下面以一段代码带你切身体会v8存取数据的逻辑。
var a=1
var b = "hellow"
var obj = {
name:'张三'
}
下面以一张图解带你了解抽象文字背后的逻辑