9大数据类型
数据类型分类
- 基础类型 7
- number
- string
- boolean
- null
- undefined
- bigint
- symbol
- 引用类型 2
- object
- 普通对象 Map
- 实例对象
- 数组对象 Set
- 正则对象
- 日期对象
- prototype原型对象
- …
- function
- object
- isNaN NaN Infinity
基础数据类型
string 字符串
使用
'' ""
和反引号``包起来的都是字符串
其他类型转换为字符串类型
- [val].toString()
- 其他类型转换为字符串,一般是使用‘’包起来
- {}普通对象调取
toSring
是调取的Object.prototype.toString
,不是转换为字符串而是检测数据类型,返回结果是"[object Object]"
- String()
- 隐式转换(一般调用toString)
+
加法运算,某一侧出现字符串,存在字符串拼接- 把对象转换为数组,需要先
toString()
转化为字符串,在转化为数字 - 基于
alert/confirm/document.write
…这些方式输出的内容,都是把内容先转化为字符串,然后再输出
- 测试题
let a = 10 + null + true + [] + undefined + '珠峰' + null + [] + 10 + false
//10+null=10
//10+true=11
//11+[]=>11+''=>'11'
//'11'+undefined=>11undefined
//'11undefined'以后为字符串拼接=>"11undefined珠峰null10false"
JS 中的加减乘除进行数学运算(如果遇到的不是数字类型,需要基于Number()方法转换位数字,在运算)加法遇到字符串会进行字符串拼接
- 字符串拼接时注意:
- 先找字符串
[] {} ''
,从头到字符前一个,数字转换相加,以后拼接字符串 - [] -> ‘’
- {} -> ‘[object Object]’’
- 数字 + undefined = NaN
- 先找字符串
number 数字
其他类型转换为数字类型
- Number([val]):先执行toString(),在进行数字转换
Number('1') //1
Number('') //0
Number({}) //NaN
Number({a:1}) //NaN
Number(undefined) //NaN
Number(null) //0
Number([]) // 0 [].toString()=>''->0
Number(['1']) // 1->['1'].toString()->'1'->1
Number([1,3]) //NaN
Number(Symbol(10)) //报错
parseInt/parseFloat([val],[进制])
:如果val是字符串,则从左至右依次查找有效数字字符,直到遇到非有效数字,停止查找(即使后面还有数字,也不返回),找到的字符当做数字返回,无有效数字返回NaN
parseInt([val],[radix])
,radix是进制不写和0都是10进制,如果value以0x开头默认为16进制- 进制取值范围:2~36之前,不在函数返回结果为NaN
- 把[value]看做[radix]进制,最后把[redix]转换为十进制
parseInt('') //NaN
parseInt({}) //NaN
parseInt([]) //NaN
parseInt(null) //NaN
parseInt(undefined) //NaN
parseInt('14px') //14
parseInt('14px3') //14
- 隐式转换
- isNaN([val])
- 数学运算(+运算比较特殊,可能是字符串拼接)
- == 进行比较时,可能出现把其他类型转换为数字的情况
++i
和i++
都是数学中的累加1
let i = 1
5 + (i++) // 5 + 1 = 6、 i = 2
i = 1
5 + (++i) //5 + 2 = 7、 i = 2
- 特殊值NaN
NaN == NaN
falseObject.is(NaN,NaN)
trueisNaN(NaN)
true
- Infinity 无穷大
把一个值转化为十进制 :[位权值:每一位的权重,…个位是0,十位是1…]
-
例:147(八进制)-> 十进制 =
1*8^2 + 4*8^1 + 7*8^0
1*8*8 + 4*8 +7*1
-
例:12.88(4进制)-> 十进制 =
1*4^1 + 2*4^0 + 8*4^-1 + 8*4^-2
1*4 + 2*1 + 8*(1/4) + 8*(1/(4*4))
boolean 布尔型
只有两个值:true false
其他类型转换为布尔类型
0
null
NaN
undefined
''
五个值转换为false
,其余转换为true
- Boolean([val])
!!
相当于转换为布尔!
转化为布尔取反- 隐式转换
- 除了在
if
里==
!==
===
>=
都要先把值转换为布尔类型
- 除了在
function getNum(){
if('3px'+3){ //字符串拼接
return 3
}
}
getNum() //3
function getNumber(){
if('3px'-3){ //NaN-3->NAN
return 3
}else{
return 2
}
}
getNumber() //2
在==比较的过程中,数据转换规则
- 类型一样的几个特殊点
- {} == {} false 对象比较的是最内存的地址
- [] == [] false
- NaN == NaN false
- 类型不一样的转换规则
- null==undefied:true,但是换成 === 则为false,(因为类型不一致),剩下的null/undefined和其他任何数据类型值都不相等
- 字符串==对象 要把对象转换为字符串
- 剩下如果==两边数据类型不一致,都是需要转换为数字在比较
- 练习题
console.log([] == false)
console.log(![] == false)
- 练习题解析
[] == false
- 对象==布尔 都转换为数字
- 对象转换为数字:先toString转换为字符串(应该是先基于valueof获得原始值,没有原始值再去toString)在转换为数字
[] -> '' -> 0
false -> 0
true -> 1
0 == 0 -> true
![] == false
- !的计算优先级大于==,先计算
![]
数组转换为布尔然后去反false
false == false -> true
- !的计算优先级大于==,先计算
null 空对象指针
意料之中,设置默认值,后期赋值
一般使用null作为初始值,0在栈内存中有自己的存储空间,占位
undefined 未定义
意料之外
let a;//undefined
symbol 创建唯一值
Symbol([value])
console.log(Symbol('A')==Symbol('A'))//false
bigint大数据值
const alsoHuge = BigInt(9007199254740991)// 9007199254740991n
综合练习
parseInt('12px') + parseInt('14px') +typeof parseInt(null)
//12 + 14 + typeof 'number'->26number
isNaN(Number(!!Number(parseInt("0.8"))))
//isNaN(Number!!(NUmber(0.8))) isNaN(有效数字) false
typeof !parseInt(null) + !isNaN(null)
// boolean true
let result = 10 + false + undefined + [] + 'yes' + null + true + {}
console.log(result)
// + 先找字符串([] {} ''),从头到字符前一个,数字转换相加,以后拼接字符串
//10+0+NaN=NaN+''+yes+null+true+'[object Object]'
//NaNyesnulltrue[object Object]
引用数据类型
对象数据类型object
- {} 普通对象:任何一个对象都是由零到多组键值对(属性名:属性值)组成的(并且属性名不可以重复)
let person = {
name:'丽丽',
2:123
}
//无属性名
person.sex //undefined
//数字对象
person[2] //123
- [] 数组对象:特殊对象数据类型,在中括号中设置属性值,属性名是默认从0开始递增的生成的数字,默认自动带length属性,存储数组长度
/^(\d|([1-9])?$/
正则对象- Math 数据函数对象
- 日期对象
函数数据类型function
函数就是一个方法或者一个功能体,实现某个功能的代码放到一起,进行封装,重复使用某个功能,直接调用函数即可=>封装=>减少页面冗余代码,提高代码重复使用率(低耦合,高内聚)
- 创建函数
- 形参
- 返回值
- 执行函数
- 实参
- arguments:函数内置的实参集合
- 类数组集合,集合中存储着所有函数执行时,传递的实参信息
- 不论是否设置形参,arguments都存在
- 不论是否传递实参,arguments也都存在
- arguments.callee:存储的是当前函数本身(JS严格模式下禁止使用)
- 函数底层运行机制
任意数求和
假设存在函数sum,求多个值的和
- 传递实参个数不确定
- 传递的值数据类型不定(是否为有效数字)
- 目的:把有效数字进行相加
function sum(){
...
}
sum(1,2)
sum(1,2,3)
sum(1,2,'a')
- 使用arguments,查看参数。
function sum(n,m){
console.log(arguments,n,m)
}
sum(1,2)
sum(1,2,3)
sum(1,2,'a')
arguments集合中存储着所有函数执行时,传递的实参信息,length为参数个数
实现sum函数
由上可知,非数字类型求和成了拼接字符串,需要控制参数类型
ES6 箭头函数实现,无数据类型校验
let sumES6 = (...args) => eval(args.join('+'))
数据类型关系
基本类型:按值操作(也叫值类型)
引用类型:操作堆类型地址(引用地址操作)
引用类型练习题
数组引用执行机制
let x = [10,20]
let y = x
let z = y
y = [30,40]
z[0] = 50
x[2] = 60
y[1] = 70
console.log(x,y,z)
let x = [10,20]
、y=[30,40]
是新增,新增值新增引用地址创建堆,y[1]
、 z[0]
是修改,修改变量属性查询引用地址,修改堆属性值
连等于引用值
let m = { x:1} //->m->AAAFFF000->{x:1}
let n = m //n->AAAFFF000
m.x = m = { x:2 }
/** m.x={x:2}->mx.x=AAAFFF111->{x:2},
AAAFFF000->{x:1,x:{x:2}},
m->AAAFFF111->{x:2}
*/
console.log(m.x)//undefined
console.log(n) //{x:1,x:{x:2}}
堆的嵌套
let a = { n:1 }
let b = a
a.x=b
console.log(a)
//{n:1 x:{n:1,x{n:1,x:{...}}}}无限循环,形成了堆的嵌套,内存溢出
js 样式使用
猜测一下,每个div内文字的颜色是什么?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实战</title>
</head>
<body>
<div id="box">颜色测试red</div>
<div id="box-yellow">颜色测试yellow</div>
<div id="box-blue">颜色测试blue</div>
<script>
let box=document.getElementById('box')
let boxYellow=document.getElementById('box-yellow')
let boxStyle=boxYellow.style
boxStyle.color='red'
let boxBlue=document.getElementById('box-blue')
let boxStyleColor=boxBlue.style.color
boxStyleColor='blue'
</script>
</body>
</html>
代码执行效果
结果分析