关于JS基本数据类型

基本数据类型

  • undefined:已声明对象但未进行初始化
  • null:空对象的引用
  • boolean: true、false
  • number
  • string
转换为true 转换为false
Boolean true false
string 空串 非空串
number 非零 0或NaN
obj 任何对象 null
undefine (不可用) undefine

JS的堆栈存储

堆是堆内存的简称,栈是栈内存的简称。

堆是动态分配内存,内存大小不一,也不会自动释放。栈是自动分配相对固定大小的内存空间,并由系统自动释放.

JS的数据类型

  • 基本数据类型
    Undefined、Null、Boolean、String、Number、Symbol都是直接按值直接存在栈中,每种类型的数据占用的内存空间大小都是固定的,并且由系统自动分配自动释放
  • 引用数据类型
    Object,Array,Function这样的数据存在堆内存中,但是数据指针是存放在栈内存中的,当我们访问引用数据时,先从栈内存中获取指针,通过指针在堆内存中找到数据

上面加粗部分字体很关键!!!容易被坑

.
答:

  • 三个变量均存储在栈中
  • 执行完后a.i的值依然是op

再来看下面的代码:

1
2
3
let arr_origin = [1,2,3,4,5];
let arr_copy = arr_origin;
let arr2 = arr_origin[2];

如果执行下面代码:

1
2
arr_copy[1] = 'change1'
arr2 = ‘change2’

我们发现arr_origin中的下标是1的值变成change1,但是下标是2的值并未变化。原因是:arr_copy是arr_origin栈指针的引用,并未开辟新的内存空间,但是arr2是在栈内存中独立存在,所以会产生上述结果。熟悉此原理,则数据的深浅拷贝就不难理解了!

number类型

  • 十进制:直接输入
  • 八进制(严格模式无效):以0开头
    070——56
    079——无效,解析为79
  • 十六进制:0x开头
    0xA——10
  • 浮点数值
1
2
3
var a = .1 //解析为0.1,不推荐
var b = 1. //解析为1
var c = 1.0 //解析为1

应该尽量避免使用浮点数计算测试

0.1 + 0.2 != 0.3

原因:因为 JS 采用 IEEE 754双精度版本(64位),并且只要采用 IEEE 754的语言都有该问题

我们都知道计算机是通过二进制来存储东西的,那么 0.1 在二进制中会表示为

1
2
// (0011) 表示循环
0.1 = 2^-4 * 1.10011(0011)

我们可以发现,0.1 在二进制中是无限循环的一些数字,其实不只是 0.1,其实很多十进制小数用二进制表示都是无限循环的。这样其实没什么问题,但是 JS采用的浮点数标准却会裁剪掉我们的数字。

IEEE 754 双精度版本(64位)将 64 位分为了三段

第一位用来表示符号
接下去的 11 位用来表示指数
其他的位数用来表示有效位,也就是用二进制表示 0.1 中的 10011(0011)

那么这些循环的数字被裁剪了,就会出现精度丢失的问题,也就造成了 0.1 不再是 0.1 了,而是变成了 0.100000000000000002

1
0.100000000000000002 === 0.1 // true

那么同样的,0.2 在二进制也是无限循环的,被裁剪后也失去了精度变成了 0.200000000000000002

1
0.200000000000000002 === 0.2 // true

所以这两者相加不等于 0.3 而是 0.300000000000000004

1
0.1 + 0.2 === 0.30000000000000004 // true

那么可能你又会有一个疑问,既然 0.1 不是 0.1,那为什么 console.log(0.1) 却是正确的呢?

因为在输入内容的时候,二进制被转换为了十进制,十进制又被转换为了字符串,在这个转换的过程中发生了取近似值的过程,所以打印出来的其实是一个近似值,你也可以通过以下代码来验证

1
console.log(0.100000000000000002) // 0.1

解决方案:

1
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 // true

数值范围

  • 最小数值:Number.MIN_VALUE
  • 最大数值:Number.MAX_VALUE
  • 无穷大:Infinity
    确定一个数是不是有穷的:isFinity()

NaN

  • 含义:非数值
  • 关注点:所有涉及NaN的操作,都会返回NaN
  • 在使用 ===== 时,NaN不等于自身,但是使用Object.is(NaN,NaN)结果是true
  • isNaN()函数:参数接收任何类型,并尝试转换为数值,若无法转换,则返回true。若参数是一个对象,则先调用参数的valueOf,再调用toString
    例子:
1
2
3
4
5
isNaN(NaN) //true
10 //false
'10' //false
'blue' //true
true //false

Number()

  • Boolean:返回1或0
  • null:0
  • Number:直接返回
  • undefine:NaN
  • String:
    只包含数字:忽略前导零后返回
    空串:0
    有效的十六进制:“Oxf”~15
    其他:NaN
  • Object:调用valueOf,若返回NaN,则调用toString

parseInt

规则:从第一非空格字符开始,如果第一个字符不是数字或符号,则返回NaN,否则解析知道第一个非数值字符

1
2
3
4
5
6
'123bule' //123
'' //NaN
'0xA' //10
'22.9' //22
'070' //56
'70' //70

注意:对于‘070’这种,ES3规范解析为八进制,ES5解析为十进制

parseFloat

规则与上述相同
注意:这个方法只解析十进制,不解析十六进制,对于十六进制串,直接返回0

String

string是JS的一个基本数据类型,但是,它同时也是JS的一个包装类型

string有两种表现形式:字符串字面值和 String 对象

大多数人都知道string可以这样使用:

1
2
var a = '123'
console.log(a.length) //3

于是很多人认为string是对象。这是错误的。

string作为JS基本数据类型之一,它不是Object类型这是绝对而且肯定的,只不过我们需要区分‘123’var a = new String('123')的区别:

  • ‘123’是基本数据类型string
  • a是对象
  • 前者是字面量方式,后者是对象方式

之所以我们使用字面量方式定义的字符串也可以使用一些字符对象方法,是因为JS在执行过程中自动进行了装箱操作:
内部将 ‘123’ 包装成了一个 String 对象,执行完后,再把这个对象丢弃了

toString

除了null和undefined,其他类型都具有这个方法

string()

传入一个非串值,返回字符串,内部通过调用参数的toString方法。
如果是null或者undefined, 则返回'null‘和'undefined'

注意这个函数和上面那个方法的区分

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2021 AURORA_ZXH
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信