如何存数字
十进制转二进制即可
10 转 2
31 变成二进制,将图中?填上
经过一番尝试
所以 31(十进制) = 01 1111(二进制)
不是套公式吗?程序员从来不套公式
2 转 10
100011 变成十进制 每一位乘以 2 的 N 次方,然后加起来即可 100011 = 2^5 + 2^1 + 2^0 = 35
用十六进制表示二进制
- 为什么用十六进制
- 因为二进制写起来太慢了:011110001011010
- 记住 8 4 2 1 对应 X X X X
- 从右往左每四位改写成一位: 011110001011010
- 得到 3,12,5,10;把大于9的数字改为ABCDEF
- 于是得到 3C5A,你也可以用计算器的程序员模式
- HEX 表示 16 进制,BIN 表示 2 进制
- OCT 表示 8 进制,DEC 表示 10 进制
如何存字符
用 0~127 表示所有符号
重点记:0——48、A——65、a——97
GB2312
中国国家标准局来编,名称为「国标2312」
用 0000~FFFF 表示汉字
- 一个16进制数是4个0/1位
- FFFF就是4x4=16位,也就是两个字节
- 最多收录 2^16 = 65536 个字符
- 但只收录了 6000 多汉字、西文字母和日文假名
- 「你」的 GB2312 编号为 C4E3
- 「牛」的 GB2312 编号为 C5A3
GBK
微软推出了一个国标扩展,简称GBK
含21886个汉字和图形符号,收录了中日韩使用的几乎所有汉字,完全兼容 GB2312,依然使用 16 位(两字节)
后来国标局推出 GB18030 取代 GBK,GB18030 不兼容 GB2312
Unicode
万国码
优点
已收录 13 万字符(大于 16 位),全世界通用,以后还会继续扩充,不会停止,最新版只添加了一个字——令和的合体字
缺点
两个字节不够用,每个字符要用三个及以上字节,这样所有文件都扩大 50%,不划算,那怎么办?
UTF-8
用 Unicode,但存的时候偷懒
- 存储「a 」
- a 对应的 Unicode 编号为 97,十六进制为 61
- Unicode 直接存: 000000000000000001100001
- UTF-8偷懒存法: 01100001
- 三字节变一字节,比GBK 还省
- 存储「你」
- 你对应的 Unicode 编号为 4F60
- Unicode 直接存: 000000000100111101100000
- UTF-8偷懒存法: 111001001011110110100000
- 还是三字节,没有省,但是字母都能省一点
- UTF-8 中的 8 的意思是
- 最少可用 8 位存一个字符
UTF-8 的规则
- 以「你a」为例
- 11100100101111011010000001100001
- 如何知道上述内容表示什么字符?
- 读 8 位信息 11100100
- 发现开头有 3 个 1,说明这个字符有 3 个八位
- 于是再读两个 8 位信息 10111101 10100000
- 前面的 10 不要,其他合起来,得 0100111101100000
- 这就还原为 Unicode 的你了:
- 000000000100111101100000
- 再读 8 为信息 01100001
- 发现开头是 0,说明这个字符只占 8 位
- 这就还原味 Unicode 的 a 了:
- 000000000000000001100001
JS 中的数据类型
8种(大小写无所谓)
- 数字 number
- 字符串 string
- 布尔 bool
- 符号 symbol
- 任意大的整数 bigint
- 空 undefined
- 空 null
- 对象 object 总结:五基两空一对象
以下不是数据类型:数组、函数、日期,它们都属于 object
数字 number
64位浮点数
写法
- 整数写法: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
每个字符两个字节
- 单引号:'你好'
- 双引号:"你好"
- 反引号:
你好如果你想要在字符串里回车
let s = `这样是
可以的
用反引号很容易做到`
字符串的属性
1、string.length
'123'.length // 3
'\n\r\t'.length // 3
''.length // 0
' '.length // 1
通过下标读取字符:string[index]
let s = 'hello';
s[0] // "h"
s[5] // undefined,居然不报错
base64 转码
- window.btoa
- 正常字符串转为 Base64 编码的字符串
- window.atob
- Base64 编码的字符串转为原来的字符串
- 一般用来隐藏招聘启事里的简历
- 邮箱:ZmFuZ3lpbmdoYW5nQGZveG1haWwuY29t
- 有时候也用来自欺欺人
- 所谓的「加密」,也就能骗过一部分外行
布尔 boolean
true 和 false,注意大小写
下列运算符会得到 bool 值
- 否定运算: !value
- 相等运算: 1 == 2、1 != 2、3 === 4、3 !== 4
- 比较运算: 1 > 2、1 >= 2、3 < 4、3 <= 4
if 配 bool
if 语句常常需要判断真假
if( value ) { ... } else { ... }
问题来了,如果 value 是 bool 值还好说,如果 value 不是 bool 值咋办,谁真谁假
- 1 是真还是假,0 是真还是假
- '1' 是真还是假,'0' 是真还是假
五个 falsy 值
falsy 就是相当于 false 但又不是 false 的值
分别是 undefined、 null、 0、 NaN 、''
因此:
- 1 是真,0 是假
- '1' 是真,'0' 是真
undefined 和 null
区别:
两种空类型,没有本质区别
细节一: 如果一个变量声明了,但没有赋值,那么默认值就是 undefined,而不是 null
细节二: 如果一个函数,没有写 return,那么默认 return undefined,而不是 null
细节三: 前端程序员习惯上,把非对象的空值写为 undefined,把对象的空值写为 null, 但仅仅是习惯上而已
Symbol
推荐阅读: 方应杭:每日一题」JS 中的 Symbol 是什么?
变量声明
三种声明方式
- var a = 1
- let a = 1
- const a = 1 区别:
- var 是过时的、不好用的方式
- let 是新的,更合理的方式
- const 是声明时必须赋值,且不能再改的方式
let声明
规则
- 遵循块作用域,即使用范围不能超出 { }
- 不能重复申明
- 可以赋值,也可以不赋值
- 必须先声明再使用,否则报错
- 全局声明的 let 变量,不会变成 window 的属性
- for 循环配合 let 有奇效
const 声明
规则:
- 跟 let 几乎一样
- 只有一条不一样:声明时就要赋值,赋值后不能改
指定值同时也指定了类型:
- let a = 1
- 但是值和类型都可以随意变化
- a = 2
- a = '字符串'
类型转换
number => string
- String(n)
- n + ''
string => number
- Number(s)
- parseInt(s) / parseFloat(s)
- s - 0
- +s
x => bool
- Boolean(x)
- !!x
x => string
- String(x)
- x.toString()