一、数据为什么需要类型
数字与字符串
都是一,为什么要分 1 和 '1'
功能不同
- 数字是数字,字符串是字符串,要严谨
- 数字能加减乘除,字符串不行
- 字符串能表示电话号码,数字不行
存储形式不同
- JS 中,数字是用 64 位浮点数的形式存储的
- JS 中,字符串是用类似 UTF8 形式存储的(UCS-2)
如何存数字
- 把十进制转为二进制即可
- 然后为了存储方便 用十六进制表示二进制
如何存字符
如何存储 a b c 1 2 3 编号即可 那就是编号,然后存编号
万国码-->UTF-8
二、JS 中的数据类型
7种(大小写无所谓) 数字 number 字符串 string 布尔 bool 符号 symbol 空 undefined 空 null 对象 object 总结:四基两空一对象 以下不是数据类型 数组、函数、日期 它们都属于 object
-
数字
写法
整数写法 1
小数写法 0.1
科学计数法 1.23e4
八进制写法(用得少) 0123 或 00123 或 0o123
十六进制写法 0x3F 或 0X3F
二进制写法
0b11 或 0B11
特殊值
正0 和 负0 都等于 0,要严谨
无穷大 Infinity 、+Infinity 、-Infinity
无法表示的数字 NaN (Not a Number)
64位浮点数
JS数字的存储形式 浮点就是浮动的点,意思就是小数点会乱动 123.456 可以表示为 1.23456e10^2 也可以表示为 12345.6e10^-2
64位存储一个 number
符号占 1 位
指数占 11 位(-1023~1024)
有效数字占 52 位(开头的 1 省略)
范围和精度
范围(忽略符号位)
指数拉满、有效数字拉满,得到最大二进制数字
Number.MAX_VALUE: 1.7976931348623157e+308
指数负方向拉满、有效数字最小1,得到最小值
Number.MIN_VALUE: 5e-324
精度(有效数字)
最多只能到52+1个二进制位表示有效数字
2^53 对应的十进制是 9 后面 15 个零
所以15位有效数字都能精确表示
16位有效数字如果小于 90 开头,也能精确表示
9110000000000001 就存不下来
-
字符串 string
每个字符两个字节(阉割版 UTF8)
单引号 '你好'
双引号 "你好"
反引号
你好
注意 引号不属于字符串的一部分,就像书名号不属于书名的一部分一样
转义
- 错误写法 'it's ok'
JS 引擎会认为 'it' 就结束了,后面的看不懂
- 正确写法
'it's ok' // 这就是转义
"it's ok"
it's ok
转义
用另一种写法表示你想要的东西 ' 表示 '
" 表示 "
\n 表示换行
\r 表示回车
\t 表示 tab 制表符
\ 表示 \
\uFFFF 表示对应的 Unicode 字符
\xFF 表示前 256 个 Unicode 字符
多行字符串
如果你想要在字符串里回车 let s = `这样是
可以的
用反引号很容易做到`
字符串的长度
string.length
'123'.length // 3
'\n\r\t'.length // ?
''.length // 0
' '.length // 1
通过下标读取字符
string[index]
let s = 'hello';
s[0] // "h"
注意 index 从 0 开始
s[0] 是第一个字符
注意 index 到 length
let s = 'hello';
s[5] // undefined,居然不报错-
s[4] // 'o'
## 布尔 boolean
只有2个值 true 和 false,注意大小写
if配合布尔
if 语句常常需要判断真假
if( value ) { ... } else { ... }
5个falsy值
falsy 就是相当于 false 但又不是 false 的值
分别是 undefined null 0 NaN ''
undefined 和 null 两种空类型
区别
没有本质区别
细节一 如果一个变量声明了,但没有赋值,那么默认值就是 undefined,而不是 null
细节二 如果一个函数,没有写 return,那么默认 return undefined,而不是 null
细节三 前端程序员习惯上,把非对象的空值写为 undefined,把对象的空值写为 null 但仅仅是习惯上而已
变量声明
三种声明方式
var a = 1
let a = 1
const a = 1
a = 1
区别
var 是过时的、不好用的方式
let 是新的,更合理的方式
const 是声明时必须赋值,且不能再改的方式
最后这种方式是错误的,不准这样声明
let声明
规则
遵循块作用域,即使用范围不能超出 { }
不能重复申明
可以赋值,也可以不赋值
必须先声明再使用,否则报错
全局声明的 let 变量,不会变成 window 的属性
for 循环配合 let 有奇效
name 和 'name'的区别
name 是变量
值可变,可能是 'name',也可能是 'hello'
'name' 是字符串常量
常量就是不变量
'name' 只能是 'name',不能是其他值
类型转换
number => string
String(n)
n + ''
string => number
Number(s)
parseInt(s) / parseFloat(s)
s - 0
x => bool
Boolean(x)
!!x
x => string
String(x)
x.toString()