JavaScript数据类型

252 阅读6分钟

数据

  • js中,数字用64位浮点数的形式存储的
  • js中,字符串用类似UTF-8形式存储的
  • 数字不以零开头

如何存放整数

  • 十进制转二进制:除2取余,逆序排列
  • 二进制转十进制
  • 用十六进制表示二进制,因为二进制太长了,用一位十六进制可以表示4位二级制的数,从右往左每四位改写成一位

如何存放字符

  • 第一次是用0到127定义了128个字符的ascll码,之后所有字符表都兼容ascll码
  • 之后国标局发布了GB2312,用16进制(从0000到FFFF)来编号。占用两个字节。然后储存时便会把这些十六进制数字变成二进制数字储存,共收入汉字6763个和非汉字图形字符682个。
  • 微软利用GB2312未使用的编码空间,扩展了GB2312的范围,含21886个汉字和图形符号,收录了中日韩使用的几乎所有汉字,完全兼容GB2312,这就是GBK
  • 之后Unicode出现将世界上所有的符号都纳入其中的一个字符集,已收录13万字符(大于16位),全世界通用。而且一直在更新中。每个字符占三个及以上字节。所以很占内存。
  • 为了节省空间UTF-8编码诞生,UTF-8编码规则:如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。

问题

  • 最后都是都是存数字0101010101,计算机咋知道你存的是数字的010101还是字符的01010101,计算机不知道。需要我们用一些辅助方式提醒计算机,比如加后缀(.txt就是存字符的编码,Excel就是存数字的数字),或者靠其他约定比如HTML文件中会约定编码形式

JavaScript的数据类型

  • 数值(number):整数和小数(比如1和3.14)
  • 字符串(string):文本(比如Hello World)。
  • 布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
  • 符号(symbol)
  • undefined:表示“未定义”或不存在,即由于目前没有赋值,所以此处暂时没有任何值
  • null:表示空值,即此处的值为空。
  • 对象(object):各种值组成的集合。

布尔值boolean

  • 不同语言布尔值转换规则不一样
  • 前置逻辑运算符: ! (Not)
  • 相等运算符:===,!==,==,!=
  • 比较运算符:>,>=,<,<=
  • 如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。
  • undefined null false 0 NaN(not a number) ""或''(空字符串)

number

  • NaN不等于任何值,包括它本身。NaN与任何数(包括它自己)的运算,得到的都是NaN。
  • 正零和负零几乎所有场合,正零和负零都会被当作正常的0。唯一有区别的场合是,+0或-0当作分母,返回的值是不相等的。
  • Infinity有正负之分,Infinity表示正的无穷,-Infinity表示负的无穷。
  • Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。
  • 以64位浮点数存储,JavaScript语言的底层根本没有整数,所有数字都是小数无论十进制是整数还是小数都先转化成二进制
  • 注意下图52位保存的只是有效数字
  • 把指数部分11位和有效数字的52位全设为1,可得最大的二进制数字换成十进制为 Number.MAX_VALUE: 1.7976931348623157e+308
  • 指数负方向拉满、有效数字最小1,得到最小的二进制数字换成十进制为Number.MIN_VALUE:5e-324
  • 符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。JavaScript 提供的有效数字最长为53个二进制位即十进制9007199254740992(有效数字)

字符串

  • js的编码是阉割版的utf-8,每个字符两个字节
  • 单引号:如'你好'
  • 双引号:如"你好"
  • 反引号:如你好 ,在反引号中可以直接回车,不用转义
  • 用另一种东西表示你想要的东西就是转义,每个转义是一个字符
  • 字符串不该有属性!只有对象才有属性。至于为什么,学完对象再来
  • 字符串的长度string.length
  • 通过下标读取字符string[index]

undefined和null

  • null与undefined都可以表示“没有”,没有本质区别
  • 如果一个变量声明了,但没有赋值,那么默认值就是undefined,而不是 null
  • 如果一个函数,没有写return,那么默认return undefined,而不是null
  • 前端程序员习惯上,把非对象的空值写为undefined,把对象的空值写为null,但仅仅是习惯上而已
  • undefined是系统默认的没有值,而null是人为认定的没有值,本质上没有区别

变量的声明

  • var a = 1;过时的
  • const a = 1;常量
  • let a = 1;变量
  • a = 1;错误的(不会声明一个全局变量只有没有改变量是才是)
  • 变量声明后,即指定了值也指定了类型,但是值和类型还是可以随意再变化的

let声明

  • let a=1是目前最新的、更合理的方式
  • 遵循块作用域,即使用范围不能超出{ }
  • 不能重复声明
  • 必须先声明再使用,否则报错(不会变量提升)
  • 全局声明的let变量,不会变成window的属性
  • for循环配合let有奇效

const声明

  • 声明时就要赋值,赋值后不能改
  • 其他和let一样

类型转换

一、number => string

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

二、string => number

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

三、转为布尔

  • Boolean(x)
  • !!x一个感叹号可把任何东西取反布尔值,再来一个就是反布尔值的反布尔值,也就是原始布尔值

四、转字符

  • x.toString()
  • String(x)
  • 数字1不可用上面的,因为默认1.后面应是小数。bug!
  • (1).toString()
  • 1..toString()
  • 1 .toString()

关于变量提升和let

  • 旧版var所有的变量的var声明语句,都会被提升到代码的头部,这就叫做变量提升
  • let 有暂时死区,不会被提升。let只会提升创建,创建create、初始化initialize 和赋值assign

name和"name"

  • 一个是变量一个是字符串