数据类型
JavaScript的数据类型有两大类:基本数据类型和引用数据类型。
- 基本数据类型(原始数据类型):
Number、String、Boolean、undefined、null 、symbol(ES6),bigint(ES10) - 引用数据类型:object(Array、Date、RegExp、Function)
1. 数值型
整型:1 2 3 4 5 6......
浮点型:314.15e-2 = 3.1415
2. 字符串型
"hello world"
3. 布尔型
true false 真和假
4. 未定义型 undefined
5. 空 null
类型是object
undefined和null 比较
undefined == null //true js规范里面规定,它俩就是相等的
undefined === null //false 两者类型不同
转为布尔型时,都是false
转为数值型时,undefined是NaN;null是0
判断数据类型 ---typeof
这个关键字可以判断的类型有:
Number,String,boolean,Undefined,Object,Function
判断不了数组
数据类型转换
- 隐式转换
- 强制转换
1、隐式转换:运算过程中自动发生的转换
(1) 数值+字符串 数值转为字符串
1+‘1’ // ‘11’ 拼接
(2)数值+布尔型 布尔型转为数值型 true-1 false-0
1+true //2
1+false //1
(3)布尔型+字符串 布尔型转为字符串
true+‘1’ // ‘true1’ 拼接
加减乘除:
有一个是字符串,则另一个也会转为字符串,最后拼接
其它情况,非数字的转换为数字
特殊:
数值+underfined=NaN
数值+null=数值
任何值和NaN执行预算,结果还是NaN
underfine转数值是NaN null转数值是0
加号的作用:
加法运算 / 字符串拼接
2、强制转换
(1)强转数值
Number()
(2)强转整型parseInt( )
-向下取整
(3)强转浮点parseFloat()
(4)强转字符String()
、toString()
PS:不是数字的强转为数字会返回NaN(not a number)
3. JS三种常见类型转换
1)转布尔型 :Boolean(原值)
原始值 | 结果 |
---|---|
number | +0、-0、NaN 以外都是true |
string | 空以外都是true |
undefined、null | false |
引用类型 | true |
2)转字符串: 原值.toString()
或String()
null和undefined没有.toString()
方法
原始值 | 结果 |
---|---|
number | 1 == > ‘1’ |
Boolean | true == > ‘true’ |
function | function(){} == > ‘function(){}’ |
数组 | [1,2] == >'1,2’ |
对象 | {name:“xiaoming”} == >"[object Object]" |
3)转数字 Number()
原始值 | 结果 |
---|---|
string | ‘1’ == > 1, ‘a1’ == >NaN |
数组 | [] ==> 0,只有一个数值型元素时直接转数字,其他转NaN |
null | 0 |
undefined | NaN |
除了数组以外的引用类型 | NaN |
补充:
- 栈内存和堆内存
举个栗子:
var a = 1;
var b = a;
var c = {name:"tom"};
var d = c;
在内存里存放的结果大致如下图所示:
栈内存主要用来存基本数据类型,比如a和b,在栈内存里存的就是这两个变量的值;
堆内存一般用来存引用数据类型,比如c和d两个对象,栈内存里存的是两个对象的内容 {name:"tom"}
引用数据类型的存储需要分配两个内存:一个是栈内存,一个是堆内存
堆--存数据
栈--存地址
通过栈内存里存的地址去堆内存里拿到对应的内容
- 值传递和引用传递
var a = 1;
var b = a;
b = 2;
b = "hello world";
b = a 是一个值传递的过程
把 a 的值传给 b
b 不会影响 a
var c = {name:"tom"};
var d = c;
d.name = "Merry";
d = {age : 15};
d.name="tom";
c = ??
d = ??
d = c 是一个引用传递的过程
c 把 地址 传给 d
在内存里的表现其实就是c和d指向同一个区域
c 和 d 任一方的改变都会影响到彼此
结果:
c = {name: "Merry"}
d = {age: 15, name: "tom"}
一开始 c 和 d 指向同一个区域
d.name 就是 c.name
所以改变 d.name 就是改变 c.name c = {name: "Merry"}
后来 d 赋新值了,也就是开辟了一个新内存,就此和 c 脱离关系,彼此之间的name就没关系了