JavaScript基本数据类型

266 阅读10分钟

数据需要类型

  • 数字和字符串

    • 1'1'两种看似一样,在计算机世界中却有很大的区别
  • 功能不同

    • 数字是Number, 字符串是String
    • 数字可以加减乘除,字符串不行
    • 字符串能表示电话号码,数字不行
  • 存储形式不同

    • 数字以64位浮点数的形式存储
    • 字符串以类似UTF8的形式存储(ucs-2)

进制转换

10进制转2进制

将一个十进制数除以二,得到的商再除以二,依此类推直到商等于一或零时为止,倒取除得的余数,即换算为二进制数的结果。只需记住要点:除二取余,倒序排列。

由于计算机内部表示数的字节单位都是定长的,以2的幂次展开,或者8位,或者16位,或者32位....。于是,一个二进制数用计算机表示时,位数不足2的幂次时,高位上要补足若干个0。本文都以8位为例。

2进制转10进制

二进制转十进制的转换原理:从二进制的右边第一个数开始,每一个乘以2n次方,n0开始,每次递增1。然后得出来的每个数相加即是十进制数。例如:100011 = 2^5 + 2^1 + 2^0 = 35

2进制转16进制

方法为:与二进制转八进制方法近似,八进制由三个二进制数表示,十六进制是四个二进制数表示。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0)。

为什么使用16进制

  • 2进制写起来耗时:011110001011010
  • 8 4 2 1分别对应 X X X X,从右往左数
  • 每四位改成一位:011 1100 0101 1010
  • 得到3,12,5,10。然后把大于9的数字改成ABCDEF,最后得到3C5A
  • HEX(Hexadecimal)表示16进制,DEC(Decimal)表示10进制,OCT(Octonary)表示8进制,BIN(Binary)表示2进制

以上资料来源

如何存储字符

使用编号来存储字符

编号规则

  • 0 表示结束字符,48 表示0
  • 10 表示换行
  • 13 表示回车
  • 32 表示空格
  • 3347表示标点
  • 4857表示数字符号
  • 6590表示大写字母
  • 97122表示小写字母
  • 127表示删除键

中文编号

编号规则

  • GB2312
  • 使用0000~FFFF表示汉字
  • 因为一个16进制是40/1位,FFFF就是4x4=16位,占用两个字节
  • 最多收录 2^16 = 65536个字符,但是只收录了6000多汉字,西文字母和日文假名
  • ‘你’ 的GB2312标号为 C4E3

GBK的出现

微软推出了一个国际拓展,简称GBKGBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1

Unicode万国码

收录13万字符,全世界同意,以后还会扩充,不会停止。缺点是两个字节不够用,每个字符需要3个及以上的字节。如果是这样的话,所有文件都扩大50%

UTF-8的发明

存储方法, UTF-8中的8意思是最少可以用8位存储一个字符

例子1

  • 例如aUnicode编号为9716进制为61
  • Unicode为:00000000 00000000 01100001
  • UTF-8为:01100001
  • 减少了两个字节,只剩一个字节

例子2

  • 例如‘你’的Unicode编号为4F60
  • Unicode为:00000000 01001111 01100000
  • UTF-8为:11100100 1011101 10100000
  • 这里没有节省字节

方法解释, 例子:‘你a’ 如何读取字符?

  • 11100100 10111101 10100000 01100001
  • 首先读取开头8位信息 1110 0100。发现开头有31,说明这个字符占有38
  • 再读取剩余两个8位,有10 11110110 100000
  • 去除前面的1110,10,10,合并得到0100111101100000
  • 还原得到Unicode的你:0000000 01001111 01100000
  • 接着读最后80110 0001
  • 首先读取开头信息,发现开头是0,说明这个字符只占有8
  • 还原得到Unicodea: 00000000 00000000 01100001

数据类型分类

JavaScript语言的每一个值,都属于某一种数据类型。

  • JavaScript 的数据类型,共有7种。通常,数值、字符串、布尔值这三种类型,合称为原始类型primitive type)的值,即它们是最基本的数据类型,不能再细分了。

  • 对象则称为合成类型complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。至于undefinednull,一般将它们看成两个特殊值。

Number数字

整数和小数(比如13.14

写法

  • 整数1
  • 小数0.1
  • 科学计数法1.23e4
  • 2进制写法0b11或0B11
  • 8进制写法0123001230o123
  • 16进制写法0x3F0X3F

特殊值

  • 0和负0都等于0
  • 无穷大位infinity,+Infinity,-Infinity
  • 无法表示的数字NaN(Not a Number),其实是数字

JS数字的存储形式-64位浮点数

  • 浮点就是浮动的点,意思是小数点会乱动

  • 123.456可以表示为1.23456e10^2,也可以表示为12345.6e10^-2

  • 64位存储一个Number,其中符号(-+ )占1位,指数占11位(-1023~1024),有效数字占52位(开头的1省略)

  • 例如0.5的二进制是0.1,0.1等于1乘以2的负一次方,最后为0 -1 0

范围(忽略符号位)

  • 指数拉满,有效数字拉满,最大二进制数字为Number.MAX_VALUE:1.7976931348623157e+308
  • 指数负方向拉满,有效数最小,最小二进制数字为Number.MIN_VALUE:5e-324

精度(有效数字)

  • 最多只能到52+1个二进制,来表示有效数字
  • 2^53对应的十进制是9后面15015位的有效数字都能准确表示
  • 16位有效数字如果小于90开头,也能精确表示。9110000000000001就存不下来

String字符串

文本(比如Hello World

写法

  • 单引号'Hello'
  • 双引号"Hello"
  • 反引号`Hello`
  • 引号不属于字符串的一部分,例如'it's ok', JS引擎解析到'it'就结束了
  • 正确的写法'it\'s ok',"it's ok",`it is ok`

转义-用另外一种写法表示你想要的东西

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

多行字符串里回车

let s = `这是第一行
这是第二行
这是第三行
`

字符串的属性-长度

string.length''.length0' '.length1,因为空格是一个字符串

通过下标读取字符

string[index],例如let s = 'abc', s[0]a,s[4]undefined

Base64 转码

  • 正常字符串转为Base64编码的字符串, 例如: window.botoa(123), 结果为MTIz
  • Base64编码转为原来的字符串,例如: window.atob(MTIz), 结果为123
  • 可以用来隐藏招聘启事里的简历, 例如: 邮箱为Y2F2YWxpZXJzMjZAc2luYS5jbg==

boolean布尔值

表示真伪的两个特殊值,即true(真)和false(假)

以下运算符会得到布尔值

  • 否定运算 !value
  • 相等运算1 == 2,1 != 2, 3 === 4, 3 ! == 4
  • 比较运算1>2,1 >=2,3<4,3<=4

5个falsy值

  • falsy相当于false,但是不是false的值。分别是undefined,null,0,NaN, ''
  • ''' '不一样,

Symbol符号

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。 Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

let s = Symbol();

typeof s
// "symbol"

上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量sSymbol 数据类型,而不是字符串之类的其他类型。

注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol 是一个原始类型的值,不是对象。也就是说,由于Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

Undefined和Null

  • nullundefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefinednull,没有本质区别。
  • 如果一个变量声明了,但没有赋值,那么默认值就是Undefined,而不是null
  • 如果一个函数,没有写return,那么默认return undefined,而不是null
  • 前端程序员习惯上,把非对象的空值写为undefined,把对象的空值写为null

Object对象

对象是最复杂的数据类型,又可以分成以下类型。

  • 狭义的对象(object
  • 数组(array
  • 函数(function
  • 日期(date

变量声明

三种声明方式

  • var a = 1,指定值也制定了类型,但是两种都可以随意变化
  • let a = 1
  • const a = 1
  • a = 1

区别

  • var是过时的,let是可变变量,const是不可变量,声明时必须赋值
  • 最后这种,是错误的

let 声明

  • 遵循blocK作用域,范围不超过{}
  • 不能重复申明
  • 可以赋值,也可以不赋值
  • 必须先申明再使用,否则报错,以下情况会报错
{
    console.log(a);
    let a = 5;
}
  • 全局声明的let变量,不会变成window的属性
  • let配合for循环效果不错

const 声明

  • 规则和let几乎一样
  • 只有一条不一样:申明时就要赋值,赋值后不可更改

name 和'name'的区别

  • name是变量,值可变
  • 'name'是字符串常量,不可变

数据类型转换

Number => string

方法为

  • String(n)
  • n + ''

String => Number

方法为

  • Number(s)
  • pasetInt(s)或者pasetFloat(s)
  • s - 0 或者 + s或者 n + ''或者 '' + n例如let s = '123'; s - 0 ;, s123

x => boolean

方法为

  • Boolean(x)
  • !! x 例如!!1为true,!!0为false

x => String

方法为

  • String(x)
  • x.toString()

变态情况

  • 1.toString()会报错,因为会1.是小数的开始,触发小数逻辑,会停止在1.
  • 可以代替使用(1).toString()
  • 或者使用1..toString()

更多信息

JS 秘密花园

对象

符号

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