JS数据类型

184 阅读4分钟

1. 数据存储

1.1 1和'1'有什么不同

  • 前者是数字,后者是字符串
  • 数字能加减乘除,字符串不行
  • 字符串能表示电话号码,数字不行
  • JS中,数字是用64位浮点数的形式存储的,字符串是用类似UTF8形式存储的(UCS-2)

1.2 万国码Unicode

  • 已收录13万字符(大于16位),全世界通用;以后还会继续扩充,不会停止
  • 两个字节不够用,每个字符要用三个及以上字符,费内存

1.3 UTF-8

  • 最少可用8位存一个字符
  • 存字符不省内存,但存字母省内存
  • UTF-8 是 Unicode 一种存储规则,也叫字符编码规则

1.4 其他

  • ACSII码共定义了128个字符,字符0的ASCII码为48,字符A的ASCII码为65,字符a的ASCII码为97
  • 在GB2312 中,2个字节即16位可以表示所有汉字
  • HEX表示16进制,DEC表示十进制,OCT表示八进制,BIN表示二进制

2. 数据类型

2.1 数字 number

  • 写法:整数写法,小数写法,科学计数法,八进制写法,十六进制写法,二进制写法
  • 1/0=infinity,1/-0=-infinity,0/0=NaN
  • NaN是不能表示的数字,但它仍是数字。NaN !=== NaN
  • 64位浮点数:

符号占1位,指数占11位(-1023~1024),有效数字占52位(开头1省略)

  • 存储范围:Number.MAX_VALUE:指数拉满,有效数字拉满;Number.MIN_VALUE:指数负方向拉满,有效数字最小1
  • 存储精度:53个二进制位表示有效数字,2^53对应十进制是9后面15个0,所以15位有效数字都能精确表示,16位有效数字如果是小于90开头,也能精确表示,9110000000000001就存不下来

2.2 字符串 string

  • 每个字符两个字节,阉割版UTF8
  • 写法:'你好' "你好" 你好
  • 注意:引号不属于字符串的一部分
  • 转义:\'表示'\"表示"\n表示换行\rn表示回车\t表示tab制表符\\表示\\uFFFF表示对应的Unicode字符\xFF表示前256个Unicode字符
  • 在字符串里回车
let s = `今天
你
开心吗`
  • 字符串的属性

string.length

'123'.length // 3
'\n\r\t'.length // 3
''.length // 0
' '.length // 1

string[index]

let s = 'hello'
s[0] // 'h'
s[4] // '0'
s[5] // undefined,不报错
  • base64转码

window.btoa 正常字符串转码为base64编码的字符串

window.atob base64编码的字符串转码为正常字符

2.3 布尔 bool

  • 只有两个值 ture,false(注意大小写)
  • 下列运算符会得到bool值

否定运算 !value

相等运算 1===2 1!==2

比较运算 1>2 1>=2

  • 5个falsy值:undefinednull0NaN''

2.4 符号 symbol

  • Symbol 可以创建一个独一无二的值(但并不是字符串)。

2.5 空 undefined 和 null

  • 两者没有本质区别
  • 如果一个变量声明了,但没有赋值,那么默认值是undefined而不是null
  • 如果一个函数没有写return,那么默认return undefined而不是null
  • 前端开发者习惯上把非对象的空值写为undefined,把对象的空值写为null

2.6 对象 object

2.6.1 声明对象的两种语法
  • let声明
* 遵循块作用域,即使用范围不能超过{}
* 不能重复声明
* 可以赋值,也可以不赋值
* 必须先声明再使用,否则会报错
* 全局声明的let变量,不会变成window的属性
  • const声明
* 规则和let声明几乎一样
* 不同点:声明时就要赋值,赋值后不能改
2.6.2 如何删除对象的属性
delete obj.xxx 或 delete obj['xxx'] //即可删除 obj 的 xxx 属性

注意区分「不含属性名」和「属性值为 undefined」

  • 不含属性名'xxx' in obj === false

  • 含有属性名,但是值为 undefined 'xxx' in obj && obj.xxx === undefined

  • 注意 obj.xxx === undefined不能断定 'xxx' 是否为 obj 的属性

2.6.3 如何查看对象的属性
  • 查看自身所有属性
Object.keys(obj)
  • 查看自身+共有属性
console.dir(obj)

或者依次用 Object.keys 打印出 obj.__proto__

  • 判断一个属性是自身的还是共有的
obj.hasOwnProperty('toString')
  • 区分变量和字符串的属性查看方式
obj.name 等价于 obj['name']
obj.name 不等价于 obj[name]

这里的 name 是字符串

let name = 'frank'
obj[name] 等价于 obj['frank']
而不是obj['name'] 和 obj.name

这里的 name 是变量名

2.6.4 如何修改或增加对象的属性
  • 直接赋值
let obj = {name: 'frank'} // name 是字符串
obj.name = 'frank' // name 是字符串
obj['name'] = 'frank' 
obj[name] = 'frank' // 错,因 name 值不确定
obj['na'+'me'] = 'frank'
let key = 'name'; obj[key] = 'frank'
let key = 'name'; obj.key = 'frank' // 错,因为 obj.key 等价于 obj['key']
  • 批量赋值
Object.assign(obj, {age: 18, gender: 'man'})
  • 修改隐藏属性
let obj = Object.create(common)
obj.name = 'frank'
let obj2 = Object.create(common)
obj2.name = 'jack'
2.6.5 'name' in obj和obj.hasOwnProperty('name') 的区别
  • 'name' in obj用于区分'name'是不是obj的属性,如果是就输出ture,不是就输出false
  • obj.hasOwnProperty('name')用于区分'name'obj特有属性,如果是就输出ture,不是就输出false

2.7 类型转换

  • number >> string

String(n)n + '''' + n

  • string >> number

Number(s)parseInt(s)s-0

  • x >> bool

Boolean(x)!!x

  • x >> string

String(x)x.toString()