js的数据类型

237 阅读9分钟

数据为什么需要类型?新人始终不明白

数字与字符串

都是一,为什么要分 1 和 '1'

功能不同

  • 数字是数字,字符串是字符串,要严谨

  • 数字能加减乘除,字符串不行

  • 字符串能表示电话号码,数字不行

存储形式不同

  • JS 中,数字是用 64 位浮点数的形式存储的
  • JS 中,字符串是用类似 UTF8 形式存储的(UCS-2)

如何存数字

十进制转二进制即可

二进制

10 转 2

  • 31 变成二进制

1.png

  • 经过一番尝试

2.png

  • 所以 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

1.jpg

  • 你也可以用计算器的程序员模式
  • HEX 表示 16 进制,BIN 表示 2 进制
  • OCT 表示 8 进制,DEC 表示 10 进制

1.jpg

如何存字符

转成数字不就得了?但字符有几千几万

如何存储 a b c 1 2 3

编号

1.png

0 表示结束字符

10 表示换行

13 表示回车

32 表示空格

33到47表示标点

48到57表示数字符号

65到90表示大写字母

97到122表示小写字母

127表示删除键

  • 记住 0用48表示; A用65表示; a用97表示

怎样表示中文

编号表示 中国国家标准局来编

名称为「国标2312」

用 0000~FFFF 表示汉字

1.png

一个16进制数是4个0/1位

FFFF就是4x4=16位,也就是两个字节

最多收录 2^16 = 65536 个字符

但只收录了 6000 多汉字、西文字母和日文假名

「你」的 GB2312 编号为 C4E3

「牛」的 GB2312 编号为 C5A3

中国人的名字里有生僻字

李瓛 => 李*

怎么表示生僻字、繁体字、韩文呢,之前的忘了编进去

微软出手了

微软推出了一个国标扩展,简称GBK,GBK 国标扩

1.png

含21886个汉字和图形符号

收录了中日韩使用的几乎所有汉字

完全兼容 GB2312

依然使用 16 位(两字节)

后来国标局推出 GB18030 取代 GBK

GB18030 不兼容 GB2312

如何表示其他未编码国家文字

继续编号,一次解决全世界的需求

万国码Unicode

  • 优点 已收录 13 万字符(大于 16 位),全世界通用

以后还会继续扩充,不会停止

最新版只添加了一个字——令和的合体字

  • 缺点 两个字节不够用,每个字符要用三个及以上字节

这样所有文件都扩大 50%,不划算

那怎么办?

虽然用 Unicode 但存的时候偷懒

UTF-8被发明(最低八位)

  • 鸡贼的存法
  • UTF-8 是 Unicode 一种存储规则,也叫字符编码规则

存储「a 」

a 对应的 Unicode 编号为 97,十六进制为 61

Unicode 直接存: 0000000000000000‭01100001‬

UTF-8偷懒存法: 01100001

三字节变一字节,比GBK 还省

存储「你」

你对应的 Unicode 编号为 4F60

Unicode 直接存: 00000000‭0100111101100000‬

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干脆就不存了,省掉 1.png

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 转义-用另一种写法表示你想要的东西(需死记硬背)

1.jpg

多行字符串

  • 如果你想要在字符串里回车

1.jpg

  • 以前没有反引号的时候 写起来很麻烦,可以看网道教程

字符串的属性

等等,只有对象才有属性,为什么字符串也有属性 为什么字符串有属性(照理不应该有) 等学完对象才能解答

字符串的长度

  • 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')

=>"fangyinghang@foxmail.com"

  • 有时候也用来自欺欺人 所谓的「加密」,也就能骗过一部分外行

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()