数据为什么需要类型?新人始终不明白
数字与字符串
都是一,为什么要分 1 和 '1'
功能不同
-
数字是数字,字符串是字符串,要严谨
-
数字能加减乘除,字符串不行
-
字符串能表示电话号码,数字不行
存储形式不同
- JS 中,数字是用 64 位浮点数的形式存储的
- JS 中,字符串是用类似 UTF8 形式存储的(UCS-2)
如何存数字
十进制转二进制即可
二进制
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 进制
如何存字符
转成数字不就得了?但字符有几千几万
如何存储 a b c 1 2 3
编号
0 表示结束字符
10 表示换行
13 表示回车
32 表示空格
33到47表示标点
48到57表示数字符号
65到90表示大写字母
97到122表示小写字母
127表示删除键
- 记住 0用48表示; A用65表示; a用97表示
怎样表示中文
编号表示 中国国家标准局来编
名称为「国标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%,不划算
那怎么办?
虽然用 Unicode但存的时候偷懒
UTF-8被发明(最低八位)
- 鸡贼的存法
- 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
这一页看不懂就跳过,反正不考
记住去餐馆排队的比喻即可:问开头那一桌(算法是从人类活动受到的启发)
- 计算机怎么区别是数字1还是字符串1 通过辅助信息:如后缀txt文本是字符串,excel表里的是数字。
JS 中的数据类型
7种数据类型(大小写无所谓)
-
数字 number
-
字符串 string
-
布尔 bool(乔治布尔是英国数学家)
-
符号 symbol
-
空 undefined
-
空 null
-
对象 object
总结:四基两空一对象
以下不是数据类型
- 数组
- 函数
- 日期
它们都属于 object
1.数字 number
写法
- 整数写法 1
- 小数写法 0.1
- 科学计数法 1.23e4
- 八进制写法(用得少) 0123 或 00123 或 0o123
- 十六进制写法 0x3F 或 0X3F
- 二进制写法 0b11 或 0B11
特殊值
- 正0 和 负0 都等于 0,要严谨
- 无穷大 Infinity 、+Infinity 、-Infinity
- 无法表示的数字 NaN (Not a Number) 比如0/0=NaN
但它是一个数字(人类目前不知道是什么数字) NaN === NaN =>false
64位浮点数
JS数字的存储形式
- 浮点就是浮动的点,意思就是小数点会乱动
- 123.456 可以表示为 1.23456e10^2
- 也可以表示为 12345.6e10^-2
- 一般不用定点数
- 十进制的小数永远可以表示为1-9任意一个,但二进制第一位只能是1。所以1干脆就不存了,省掉
64位存储一个 number
- 符号占 1 位
- 指数占 11 位(-1023~1024)
- 有效数字占 52 位(开头的 1 省略)
例如:0.5 存储形式=>1/2= 12^-1 符号:0 指数:-1 有效数字:0 0.625存储形式===0.5+0.125===1/2+1/8===12^-1+1*2^-3 =>二进制
范围和精度
范围(忽略符号位)
- 指数拉满2^1024、有效数字拉满,得到最大二进制数字
- Number.MAX_VALUE: 1.7976931348623157e+308
- 指数负方向拉满2^-1023、有效数字最小1,得到最小值
- Number.MIN_VALUE: 5e-324
精度(有效数字)
- 最多只能到52+1个二进制位表示有效数字
- 2^53 对应的十进制是 9 后面 15 个零
- 所以15位有效数字都能精确表示
- 16位有效数字如果小于 90 开头,也能精确表示
- 9110000000000001 就存不下来
2.字符串 string
每个字符两个字节(阉割版 UTF8)
写法
- 单引号 '你好'
- 双引号 "你好"
- 反引号 ``
你好 - 注意 引号不属于字符串的一部分,就像书名号不属于书名的一部分一样
如果要在单引号里面包含单引号怎么办?使用转义
转义
错误写法
- 'it's ok'
- JS 引擎会认为 'it' 就结束了,后面的看不懂
- chrome鸡贼,写法不合法
正确写法
- 'it's ok' // 这就是转义
- 双引号"it's ok"
- 反引号
it's ok转义-用另一种写法表示你想要的东西(需死记硬背)
多行字符串
- 如果你想要在字符串里回车
- 以前没有反引号的时候 写起来很麻烦,可以看网道教程
字符串的属性
等等,只有对象才有属性,为什么字符串也有属性 为什么字符串有属性(照理不应该有) 等学完对象才能解答
字符串的长度
- string.length
- '123'.length // 3
- '\n\r\t'.length // 3(与字符串写法知识联系起来)
- ''.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'
base64 转码
- window.btoa 正常字符串转为 Base64 编码的字符串
- window.atob Base64 编码的字符串转为原来的字符串
- 一般用来隐藏招聘启事里的简历 邮箱:ZmFuZ3lpbmdoYW5nQGZveG1haWwuY29t
window.atob('ZmFuZ3lpbmdoYW5nQGZveG1haWwuY29t')
- 有时候也用来自欺欺人 所谓的「加密」,也就能骗过一部分外行
3.布尔 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 是真还是假 0是假(见五个falsy值)
- '1' 是真还是假,'0' 是真还是假 都是真
js的五个 falsy 值(死记硬背)
- falsy 就是相当于 false 但又不是 false 的值
- 分别是 undefined null 0 NaN ''(是空字符串,没有空格!)
- '' 和 ' ' 不是一个玩意。再次声明,请保持严谨!
4.undefined 和 null 两种空类型
空空如也
为什么有两个空
这是 JS 的原(la)创(ji)之处
区别
没有本质区别 默认值undefined
- 细节一 如果一个变量声明了,但没有赋值,那么默认值就是 undefined,而不是 null
- 细节二 如果一个函数,没有写 return,那么默认 return undefined,而不是 null
- 细节三 前端程序员习惯上,把非对象的空值写为 undefined,把对象的空值写为 null 但仅仅是习惯上而已
5.symbol 符号
不怎么常用的数据类型
直接看文章吧zhuanlan.zhihu.com/p/22652486
总结六种类型(大小写无所谓)
undefined null number string bool symbol
这些都是简单类型,object 叫做复杂类型,下节课学
变量声明
三种声明方式
-
var a = 1 (过时声明)
-
let a = 1 (变量声明)
-
const a = 1(常量声明)
-
a = 1(赋值,非声明全局变量)
区别
- var 是过时的、不好用的方式
- let 是新的,更合理的方式
- const 是声明时必须赋值,且不能再改的方式
- 最后这种方式是错误的,不准这样声明
var 变量提升
押题时再讲
有兴趣可以提前看网道教程wangdoc.com/javascript/…
var 声明
直接跳过
我们写代码不用 var
面试押题前单独讲解
let 声明
规则
- 遵循块作用域,即作用范围不能超出 { }
{
let b = 1
console.log(b)
}
console.log(b)
- 不能重复申明 let a = 1 let a = 2 错
- 可以赋值,也可以不赋值
- 必须先声明再使用,否则报错
- 全局声明的 let 变量,不会变成 window 的属性(对比var会改变window的属性)
- for 循环配合 let 有奇效(对比var)
const 声明
规则
- 跟 let 几乎一样
- 只有一条不一样:声明时就要赋值,赋值后不能改
变量声明
指定值
var a = 1
同时也指定了类型(非常重要)
var a = 1 number 但是值和类型都可以随意变化 a = 2 a = '字符串'
name 和 'name' 的区别
新人想不通
name 是变量(存在heap区)
- 值可变,可能是 'name',也可能是 'hello'
- 类型可变,可以是number,也可能是字符串
'name' 是字符串常量(存在stack区)
常量就是不变量
- 'name' 只能是 'name',不能是其他值
- 类型就是字符串
类型转换
number => string
- String(n) 大写String用来把不是字符串的变成字符串
n + '' 最常用方法:n+空字符串
string => number
- Number(s) 大写
- parseInt(s) / parseFloat(s) 把任何东西变成整数
s - 0 最常见方法:s减零
- +s s前面加+号
x => bool
- Boolean(x)
!!x 最常用方法,取原始布尔值
x => string
- String(x)
x.toString() 最常用方法,加后缀.toString()
特殊:1.toString在js里不合法需改成(1).toString()