数字与字符串

1'1'完全不同

功能

  • 数字能加减乘除模和值的比较,字符串不能计算值,无法进行值的大小比较(严谨的说不算隐式转换的话)
  • 字符串能表示电话号码,数字不行,数字不能表示开头是0,硬上会造成数据损失
  • 不同国家的电话号码中甚至可以有字母

存储形式

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

如何存数字

把十进制转二进制即可

二进制

10转2

有公式,但程序员不是数学家,从来不套公式,只尝试,按数位展开,按位累加

2转10

快算进制转换

用十六进制表示二进制

TL,DR

计算器程序员模式

HEX16 BIN2 OCT8 DEC10

如何存字符

转成数字,但'1'不能用1来表示

UTF8

存储abc123

编号0~127(2^7)表示所有符号

  • 0表示结束字符NUL(null)
  • 10表示换行
  • 13表示回车
  • 27表示’ESC’
  • 32表示空格
  • 33~47表示标点
  • 48~57 表示数字符号
  • 65~90表示大写字母
  • 97~122表示小写字母
  • 127表示删除键

048表示,A65表示,a97表示,其他用到再查

其他编码基本兼容以上,即前128位都为以上表示

键盘监听事件


中文字符的编码

「国标2312」

0000~FFFF表示汉字

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

FFFF就是4*4=16位,即两个字节

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

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

生僻字、繁体字、其他东亚字符无法表示

  • 国标局官方的效率差,微软出了GBK,国标扩

21886个汉字和图形符号

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

依然使用16位(两字节)

后国标局推出GB18030想取代GBK,但竟然不兼容GB2312

  • 怎么表示其他语言文字,藏文,泰文…

万国码Unicode

Unicode

优点

  • 已收录0.13M多个字符(大于16位),世界通用
  • 以后会扩充
  • 最新版(2019)添加了一个字——令和的合体字

缺点

  • 两个字节不够用,每个字符要用三个及以上的字节
  • 所有文件都扩大50%,不划算

用(读写)Unicode,存的时候简化

UTF-8

UTF-8

鸡贼的算法

存储「a」

  • a对应的Unicode编号为97,十六进制为61
  • Unicode直接存: 00000000 00000000 011000011
  • UTF-8偷懒存:011000011
  • 三字节变一字节,比GBK还省

存储「你」

  • 「你」对应Unicode编号4F60
  • Unicode直接存: 00000000 01001111 01100000
  • UTF-8偷懒失败存:11100100 10111101 10100000
  • 还是三字节,没省,但是字母都能省一点

UTF-8中的8的意思是

最少可用8位存一个字符,其他可以是16位,24位数位

UTF-8的规则

由开头的数字表示用几个8位表示

详见PDF第25页 数据类型和运算符.pdf

位运算

TL,DR

比喻:去餐厅排队


如何存字符,就是编码,然后存编码

1'1' 功能不同,存储形式不同

1是变成二进制直接存

'1'要经过编码(变成49)再存

那计算机怎么知道存的是数字还是字符?

计算机不用知道,用文件格式表示

文本格式.txt全用字符串表示,可以在另存为中,选择保存的编码

即计算机通过文件格式来约定存储的是什么

.html文件只支持字符串


拉回正题

JS中的数据类型

目前八种(截止2020,以后还会增加?)

7种原始类型(大小写无所谓只有写代码时要区分大小写)

  • 数字number
  • 字符串string
  • 布尔boolean

  • undefined

  • null

增加的

  • 符号symbolruby
  • 大型整数bigint

1种复杂类型

  • 对象object

以下不是数据类型

  • 数组、函数、日期

以上都属于object

数字number

64位浮点数

写法

一般写法

  • 整数写法:1
  • 小数写法:0.1.123

不常用

  • 科学记数法:1.2e4
  • 八进制:0123001230o123
  • 十六进制:0x3F0X3F
  • 二进制:0b110B11

特殊值

正零和负零

  • 都等于0

区别

1
2
3
4
5
6
7
8
> 1/0
< Infinity

> 1/+0
< Infinity

> 1/-0
< -Infinity

无穷大

  • Infinity+Infinity-Infinity

无法表示的数字

  • NaN(not a number)
  • 不能表示的数字,但TM还是一个数字
  • 但它不等于自己

    1
    2
    3
    4
    5
    
    > 0/0
    < NaN
    
    > NaN == NaN
    < false
    

64位浮点数

JS数字的存储形式

  • 浮点就是 ‘浮动的点’,意思是小数点会乱动
  • 123.456可以表示为1.23456e10^2
  • 也可表示为12345.6e10^-2

64位存储一个number

  • 符号占1位
  • 指数占11位(-1023~1024)
  • 有效数字占52位(开头的1省略)
JS浮点数 11位 53位
0正 指数部分(有正负) 有效数字(省去第一个1
1负 指数部分(有正负) 有效数字(省去第一个1

++±++ 1.++01100110++ x 2^++8++(二进制)

范围和精度

范围(忽略符号位)

  • 指数拉满、有效数字拉满,得到最大二进制数字
  • Number.MAX_VALUE1.7976931348623157e+308
  • 指数负方向拉满、有效数字最小1,得到最小值
  • NUmber.MIN_VALUE5e-324

精度

  • 最多只能到52+1个二进制位表示有效数字
  • 2^53对应的十进制是9之后15个零
  • 所以15位有效数字以内都能精确表示
  • 16位有效数字如果小于90开头,也能精确表示
  • 911·000·000·000·000·1 (忽略·),就存不下来

字符串string

每个字符两个字节(阉割版UTF8)

字符串string写法(ES6)

  • 单引号

‘Hi’

  • 双引号

“Hello”

  • 反引号

`Aloha`

注意

  • 引号不属于字符串的一部分,就像书名号不属于书名的一部分一样
  • 如果要在单引号里包含单引号咋办?

用转义符\

转义

用另一种写法表示你想要的东西

错误写法

  • 'it' ok'
  • JS引擎会以为'it'就结束了,后面的看不懂
  • Chrome控制台测试,不要看控制台的返回值的双引号,会扰乱视听

正确写法

  • Chrome控制台敲入以下代码试试

转义其他表示法

  • \'表示'
  • \"表示"
  • \n表示换行
  • \r表示回车
  • \t表示制表符
  • \\表示\
  • \uFFFF表示对应的Unicode字符
  • \xFF表示前256Unicode字符

    1
    2
    3
    4
    5
    
    > '\u4f60'
    < "你"
    
    > '\x31'
    < "1"
    

多行字符串string

在字符串例敲回车

1
2
3
4
let s = `这样是
可以的
用反引号很容易做到
`

以前没有反引号的时候写起来很麻烦

网道 字符串

字符串的属性

只有对象才有属性,隐式转换成了包装对象,才有了属性

字符串的长度

string.length的变态情况

  • '123'.length //3
  • '\n\r\t'.length //3
  • '\\\\\\'.length //3两个反斜杠表示一个反斜杠
  • ''.length //0 空字符串
  • ' '.length //1 空格字符串
  • 可以试试6个空格的长度,就是6

通过下标读取字符

string[index]

1
2
let s = 'hello'
s[0]  //"h"

注意index0开始

  • s[0]是第一个字符

注意index到length

1
2
3
4
let s = 'hello'
s[5] // undefined,居然不报错
s[4] //'o'
s[s.length-1] //'o'

base64转码

window.btoa(‘xxx’)

  • 正常字符串为Base64编码的字符串

window.atob(‘xxx’)

  • Base64编码的字符串转为原来的字符串

一般用来隐藏招聘启事里的简历

  • 邮箱:ZmFuZ3lpbmdoYW5nQGZveG1haWwuY29t

「加密」不可靠,有其他专门的方法

布尔boolean

真或假

只有两个值,注意大小写:truefalse

会得到bool值的运算符

否定运算

  • !value表示取反

相等运算(等性运算)

  • 1 == 2
  • 1 != 2
  • 3 === 4
  • 3 !== 4

比较运算

  • 1 > 2
  • 1 >= 2
  • 3 < 4
  • 3 <= 4

ifbool

if语句常常需要判断真假

  • if(value){...}else{...}

问题来了

如果valuebool值还好说

如果value不是bool值,比如一个表达式,咋办,孰真孰假?

1是真是假,0是真是假

'1'是真是假,'0'是真是假

五个falsy

falsy就是相当于false但又不是false的值

分别是undefinednull0NaN、``(空字符串,没空格)

加上false,一共六个假值

其他所有一切,都是真值,包括函数,空数组,空对象

  • ''' '(一个空格)不同,保持严谨
  • 把输入法的设置标点都改为在IDE应用中都使用英语标点

空类型undefinednull

JS原(la)创(ji)

undefined是补null bug补来的

区别

没有本质区别

  • 细节一:如果一个变量声明了,但没有赋值,那么默认就是undefined,而不出null

  • 细节二:如果一个函数,没有写return,那么默认return undefined,而不是null

  • 细节三:仅前端习惯上,把非对象的控制写成undefined,把对象的空值写为null,没有任何语法依据

undefined是默认空,null是主动清空

符号symbol

不常用的数据类型

「每日一题」JS 中的 Symbol 是什么?

大型整数bigInt

javascript 中基于BigInt 实现定点数 BigFixed

BigNumber.js

原生JS灵魂之问

7 个令人兴奋的 JavaScript 新特性

ES7、ES8、ES9、ES10 新特性大盘点

2020年从基础到进阶,测试你有多了解 JavaScript,刷新你的知识

ES2020新增功能

你即将使用的ES2020新功能

种草 ES2020 新特性

从 JavaScript、ES6、ES7 到 ES10,你学到哪儿了

也许也用不到

对象object

复杂类型,另开一篇笔记

变量声明

三种声明方式

1
2
3
4
var a = 1
let a = 1
const a = 1
a = 1 //错误的声明方式,起效,不规范 只是赋值 并不是声明全局变量

区别

  • var是过时的、不好用的方式,直接跳过,写业务代码不用var,演示时在控制台调试用var,可重复声明变量,面试另说
  • let是新的、更合理的方式的变量声明
  • const是声明时必须赋值,且不能再改的方式,即常量声明
  • a = 1 错误的声明方式,起效,不规范 只是赋值 并不是声明全局变量
  • 在函数外声明,挂在window上,只是window的属性,不规范,不用

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    function fn(){
    a = 1
    }
    fn()
    a
    
    function fn(){
    var a
    function f2(){
        a = 1 //并不是声明全局变量
    }
    f2()
    }
    fn()
    

var变量提升

面试必有,看 网道 变量提升

工作不准用var

let声明规则

  • 遵循块作用域,即使用范围不能超出代码块{}
  • 不能重复声明,重复声明会报错,除非在其他代码块内
  • 可以赋值,也可不赋值
  • 必须先声明,再使用,否则报错,即不会变量提升
  • 全局声明的let变量,不会变成window的属性(var会)
  • 配合for循环使用,有奇效

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    {
    let b = 1
    console.log(b)
    }
    console.log(b) //报错
    
    {
    let a = 1
    }
    {
    let a = 3 //ok
    }
    
    let c //ok
    c = 2
    
    let abc = 'abc'
    window.abc //undefined
    var abc = 'abc'
    window.abc //"abc" 属于var的bug
    

配合for循环使用,有奇效

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
for (var i = 0; i < 5; i++){
    setTimeout(()=>{console.log(i)},0)
}
< 8 //是setTimeout的ID
//打出5个5

for (let i = 0; i < 5; i++){
    setTimeout(()=>{console.log(i)},0)
}
//ok

const声明规则

  • let几乎一样
  • 只是:声明时就要赋值,赋值后不能改,即有且仅有一次赋值
  • 只读变量,即常量

变量声明的过程中,发生了什么

1
2
3
const i //报错
const i = 100
i = 101  //报错

变量声明的细节

  • 指定了值

var = 1

  • 同时也就指定了类型

var = 1

但是值和类型都可以随意变化

1
2
a = 2
a = '2'

name'name'的区别

name是变量

  • 值可变,可能是字符串'name',也可能识别的
  • 存在内存的未知区

'name'是字符串常量

  • 常量就是不变量
  • name只能是name,不是其他值
  • 存在内存的Stack栈区

类型转换

number=>string

  • String(n)
  • n + ''

string=>number

  • Number(s)
  • parseInt(s)/parseFloat(s)
  • s - 0
  • +s

parseInt(0123)返回123,不需要加参数,也默认十进制,parseInt(0123,10),是ES6之前(0开头数字以8进制转换)的bug

另一个bug:String(1000000000000000000000)返回1e21

x=>bool

  • Boolean(x)
  • !!x 取原始布尔值

x=>string

  • String(x)
  • x.toString()

bug:1.toString()报错

改为(1).toString()

或改为1..toString()

1.解析为1.0,即1.0.toString(),竟然合法


·未完待续·

参考文章

数据类型和运算符.pdf

我用了两个月的时间才理解 let

「每日一题」JS 中的 Symbol 是什么?

字符串 网道 / WangDoc.com

全面总结 JavaScript 类型相关知识点

记录JS各种奇葩bug的JavaScript 秘密花园


javascript 中基于BigInt 实现定点数 BigFixed

原生JS灵魂之问

7 个令人兴奋的 JavaScript 新特性

ES7、ES8、ES9、ES10 新特性大盘点

2020年从基础到进阶,测试你有多了解 JavaScript,刷新你的知识

ES2020新增功能

你即将使用的ES2020新功能

种草 ES2020 新特性

从 JavaScript、ES6、ES7 到 ES10,你学到哪儿了

相关文章