欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【JS之路】“简单”的数据类型

程序员文章站 2022-06-19 15:35:28
JavaScript数据类型ECMAScript规定了8种数据类型,又分为两种:简单数据类型和复杂数据类型。简单数据类型Number:整数或者浮点数(里面还包括一些特殊值,例如:Infinity 代表无穷大,-Infinity 代表无穷小,NaN(not a number))Boolean:只包含两个值 true和false字符串:用单引号或者双引号包裹起来的都叫字符串underfined:未定义的null:空在ES6+中加入了Symbol、BigInt(本文暂不作讨论)复杂数据类...

JavaScript数据类型

ECMAScript规定了8种数据类型,又分为两种:简单数据类型复杂数据类型

简单数据类型

  • Number:整数或者浮点数(里面还包括一些特殊值,例如:Infinity 代表无穷大,-Infinity 代表无穷小,NaN(not a number))
  • Boolean:只包含两个值 true和false
  • 字符串:用单引号或者双引号包裹起来的都叫字符串
  • underfined:未定义的
  • null:空

在ES6+中加入了SymbolBigInt(本文暂不作讨论)

复杂数据类型:

  • object:对象类型,平时用的包括ObjectFunctionArrayMathDate等都是特殊的对象。

为什么要区分简单数据类型和复杂数据类型

说简单点,相对于java、c++等高级语言一样,就是变量对象的区别,这种区别是可显式的。谈及变量自然离不开内存,今天我们主要以JavaScript为始,以内存的存储方式来展开。


不可变性

在ECMAScript标准中,简单数据类型被定义为primitive values,即原始数值,代表他的值是不可变的。 看到这里,肯定有读者发出疑问:JavaScript里面都是变量啊!不能改变,那不是就成常量了?
别急,我们从内存来逐步理解:
在JavaScript中,变量松散类型的,变量可以保存任何类型的数据。简单来说,每个变量仅仅是一个占位符而已,它里面可以任意存值。

JavaScript中的内存总体分为两种:内存和内存

栈内存

特点:

  • 存储空间的大小固定(即创建时的大小是确定的)
  • 总空间较小
  • 可以直接操作变量,运行效率高(因为JavaScript代码是在栈区执行的)
  • 由编译器分配空间

而JavaScript中的简单数据类型的值,其实就是存储在栈区

先看一下栈区的存储方式
【JS之路】“简单”的数据类型
下面我们通过一道简单的运算题来理解栈内存的存储模式。

	var str="abc";
	str=str+"d"; // "abcd"

上面代码中,我们对str变量进行了:str+“d”,实际上是在栈中又开辟了一块内存空间用来存储新的值“abcd”,然后将str变量指向这块新的内存空间。但是,这并不违背不可变性这一特点
【JS之路】“简单”的数据类型


引用对象

JavaScript中的对象其实就是一堆数据和功能的集合,算是一种数据结构。我们在这里说一下复杂数据类型在内存的存储方式,也就是内存。

堆内存

特点:

  • 存储空间大小不固定,可以动态调整
  • 空间很大
  • 在JavaScript代码中,无法操作其内部存储,要使用地址读取 (运行效率低)
  • 通过代码分配空间

【JS之路】“简单”的数据类型

复杂数据类型就不存在不可变性,我们可以随意改变他们的值:

	obj1.name="李四";
	obj2.age=19;

【JS之路】“简单”的数据类型


Number类型

简称数字类型,可以表示整数和浮点数。在计算机中,数据都是以二进制存储的。当进行计算的时候,数据都是以二进制的形式进行计算,然后将结果转换为十进制打印。 在这个过程中会发生一个很经典的问题:精度丢失,这个问题发生在各种语言中。这是因为存储长度的原因。

JS中对于二进制的存储方式

对于整数来说,除非超过最大范围,否则是不会存在精度问题。主要问题在于小数的存储。因为大多数小数的二进制是无限循环的。

ECMAScript中的Number类型遵循IEEE 754标准。使用64位固定长度来表示。
这其中包括:符合位指数位尾数位

对于JavaScript来说,它使用的是64位双精度浮点数编码,所以它的符号位占1位,指数位占11位,尾数位占52位。

【JS之路】“简单”的数据类型(图片来自网络,侵权删)

  • 符号位:就是表示这个数的正负关系,1表示负,0表示正
  • 指数位:存储科学计数法的指数
  • 尾数位:存储科学计数法的有效数字;

由于尾数位只能存储52位,那么对于53位的数字来说:第53位及以后的数字是不能存储的,它遵循,如果是1就向前一位进1,如果是0就舍弃的原则。这也就是为什么小数计算会产生误差,也就是经典的"0.1+0.2!=0.3"


null 和undefined

ECMAScript规定中,有两个特殊的数据类型,它们有且仅有一个值。

  • null:仅有一个值null,从逻辑上看,null表示一个空对象指针,因为当我们使用typeof操作符时,检测值为null的变量会返回 object。我们可以利用这个值来销毁一些对象的行为。
  • undefined:未定义的。当我们声明一个变量但是未对其赋值,这个变量的值就是undefined。但是有特殊情况,当你直接调用一个未声明的变量时,这个变量时undefined

因为JavaScript是一门动态语言,除了有表示空的null之外,还可能根本就不存在,但是只有在代码运行时才能知道。JavaScript中对于未初始化的变量会自动被赋予undefined


类型检测


typeof

通过typeof操作符,我们很容易能区分出各种简单数据类型。

typeof 123  // number
typeof true  // boolean
typeof '123'  // string
typeof undefined  // undefined

但对于复杂数据类型来说,因为存在特殊的对象,例如DatefunctionArray等等。

typeof [] // object
typeof {} // object
typeof new Array() // object
typeof function(){}  //function

有一个特例,也就是函数(function)。 其他都会被简单判定为object


instanceof

对于上面检测引用类型不准确的情况,instanceof操作符能很好地帮助我们解决问题。

[] instanceof Array // true
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true

instanceof操作符的原理,简单来说就是,左侧是否继承于右侧。在JavaScript中来说,左侧是否在右侧原型链上。


toString

对于引用类型来说,调用toString方法,可以实现引用类型到字符串的转换,并且返回"[object type]"。这里的type,就是这个对象的类型。

 {}.toString() //[object Object]

但是经过我测试后发现,大部分特殊的对象不能实现正确输出。原来,比如ArrayDateRegExp 等都重写了toString()方法,所以我们得不到正确答案。

那么我们怎么才能获得正确结果呢? 其实我们只要调用原始toString()方法就可以了,这时候我们就要借助原始类型上的方法:
Object.prototype.toString().call(arg) arg的值为特殊的对象。


最后

今天的分享就到这里了。虽然总结了不少细节知识,但肯定有我遗漏的知识,希望大家在阅读完毕之后提出宝贵意见!

本文地址:https://blog.csdn.net/qq_45786599/article/details/111873196

相关标签: JS javascript