数据类型是字面含义,表示各种数据的类型。在任何语言中都存在数据类型,因为数据是各种各样的。
JavaScript主要包含8种数据类型,8种数据类型可以分为基础类型和引用型两个分类:
- 基础型数据类型
- number 数字(包含整数和浮点数)
- string 字符串
- boolean 布尔值
- undefined 未定义
- null 空指针
- symbol 符号
- bigint 大整数
- 引用型数据类型
- object 对象
通常可以使用typeof
操作符查看数据类型,但是请注意,在检测null
值时返回的不是null类型,而是object类型,这是一个特例。
Number
JavaScript不区分整数、浮点数等,统一都叫Number。typeof 100
得到 "number"
。
- 数值字面量
10、1.5、-20
- 浮点数精度问题
console.log(0.1+0.2);
console.log(0.7*100);
JavaScript中采用 IEEE 754 标准 (opens new window)的 64 位双精度浮点数。数值的运行会先将数值转为二进制,而这种标准下小数可能会出现表示不全的情况,从而最终的结果出现误差。(有汇编基础的同学可以自行进一步了解)如果为了得到相对准确的结果,一般会将小数转为整数之后再进行运行,最后除以倍数。例如:console.log( (0.1*100+0.2*100)/100 );
- 数值范围根据标准,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。也就是说,64位浮点数的指数部分的值最大为2047,分出一半表示负数,则 JavaScript 能够表示的数值范围为2的1023次方到 2 的1024次方(开区间),超出这个范围的数无法表示。如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回
Infinity
。相反,最大负数为-Infinity
。Infinity
和-Infinity
也是数字的一种。 - 特殊值
NaN
是一个特殊的值,它的类型是number
,表示一个损坏的数值,通常出现在有不能转换为数字的数据参与运算时产生。
String
用来放一段文字。typeof "文字文字"
得到 "string"
。
- 字符串字面量”文字” // 双引号
‘ababa’ // 单引号
`abcd` // 反引号三种引号都可以用来表示字符串数据。 - 转义字符如果想在字符串使用引号文字:console.log( “It’s an apple.” ); //一种引号里面使用其他两种引号没有问题
console.log( “John:\”I love you.\”” ); //内部使用字面量相同的引号,则需要使用 \ 转义符号其他转义含义: - 字符串拼接进行
+
运算时,两边任意一边的数据是字符串的话,则是拼接的功能console.log(“123” + “4”); //”1234″
console.log(“123″ + 4); //”1234”
console.log(“zzt” + “666”); //”zzt666″
Boolean
布尔值类型只有两个值:真true
和 假false
。用于判断。
typeof true
得到"boolean"
。
Undefined
未定义类型的值为undefined
。
在变量没有被赋值时,默认值也为undefined
。
typeof undefined
得到"undefined"
。
Null
null
和 undefined
意义很接近,都表示“没有”。null
可以理解为一个“空”对象,但是并不占据内存空间。通常在一个变量即将在后续的逻辑中被赋予一个对象值,但是刚开始定义的时候不能确定到底是哪个对象值时,赋予它初始值null
。
注意:typeof null
得到"object"
。
Symbol
symbol是一种运用场景极少的数据类型,该类型数据在开发中,基本不会使用。所以了解即可
Symbol值不可以进行运算
Symbol实际上是ES6引入的一种原始数据类型,用它来产生一个独一无二的值。在JS中,基础数据类型通常只要“长得一样”在判断相等时,就是true
,而在某些特定场合下,我们可能会需要一些独一无二的值来保证程序正常运行,比如给对象创建属性时,不会覆盖已有属性的情况。此时就需要Symbol.
let s1 = Symbol() // 通过Symbol函数创建一个symbol数据
let s2 = Symbol() // 再创建一个
console.log(s1) // 输出结果:Symbol()
console.log(s2) // 输出结果:Symbol()
// 它们俩长得一样,但是却不相等
s1 == s2 // false
结论:每次调用Symbol()
都会在程序中,创建一个独一无二的值
BigInt
该数据类型是在ES2020版本才加入的,所以2020之前的浏览器环境是不支持的。
JavaScript在数字上一直都很糟糕,因为在没有bigint类型之前,数字只能表示-(2^53-1)
至 2^53-1
范围的值,即Number.MIN_SAFE_INTEGER
至Number.MAX_SAFE_INTEGER
,超出这个范围的整数计算或者表示会丢失精度。
var num = Number.MAX_SAFE_INTEGER; // -> 9007199254740991
num = num + 1; // -> 9007199254740992
// 再次加 +1 后无法正常运算
num = num + 1; // -> 9007199254740992
// 两个不同的值,却返回了true
9007199254740992 === 9007199254740993 // -> true
于是 BigInt 应运而生,它是第7个原始类型,可安全地进行大数整型计算。
作用:超大整数形式的ID和高精度时间戳
大多数情况下可以像常规数字类型一样使用 例如 +, -, /, *, %等等。 对bigint的所有的操作,返回的结果也是bigint
但是 5n / 2n = 2n 的结果会砍掉小数 保留整数 %同理
创建 BigInt 类型的值也非常简单,只需要在数字后面加上 n 即可。例如,123 变为 123n。也可以使用全局方法 BigInt(value) 转化,入参 value 为数字或数字字符串。
const aNumber = 111;
const aBigInt = BigInt(aNumber);
aBigInt === 111n // true
typeof aBigInt === 'bigint' // true
typeof 111 // "number"
typeof 111n // "bigint"
只要在数字末尾加上 n,就可以正确计算大数了:
1234567890123456789n * 123n;
// -> 151851850485185185047n
不过有一个问题,在大多数操作中,不能将 BigInt与Number混合使用。比较Number和 BigInt是可以的(===严格比较时 不相等),但是不能把它们相加。
1n < 2
// true
1n == 1
//true
1n === 1
//false
1n + 2
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
一元操作符 +不支持
+'1' 会转化成number处理
+1n会报错 提示无法转成number
BigInt的支持情况:
Object类型
JavaScript中object
类型包含的数据有很多,数组、普通对象、DOM节点、内置对象、函数等等都属于obejct
类型。
- 数组一个数组中可以存放一组数据。
- 取值使用
[数字序号]
下标,序号从0开始计数。取值超出序号最大值时,得到undefined
。let arr = [10,50,true,”Fly”];
console.log(arr[2]); //true
console.log(arr[6]); //undefined - 数组中可以存放数组。let arr = [
10,
[
“夏栀”,
“锦鲤”,
[
true,
false
]
]
];
console.log(arr[0]); //10
console.log(arr[1][0]); //”夏栀”
console.log(arr[2][1]); //false - 数组拥有
length
属性,可以得到数组存放的数据的个数。let a = [10,20];
let b = [7,8,9];
let c = [4,5,,6,];
console.log(a.length); //2
console.log(b.length); //3
console.log(c.length); //4 最后一个,后面没有值的话,不算个数,中间的,之间即使没有数据也算个数 - 数组可以取值,可以修改值或者新增值let arr = [4,5];
arr[0] = 44;
arr[2] = 6;
console.log(arr); // [44,5,6]
let arr2 = [7,8,9];
arr2.length = 2;
console.log(arr2); //[7,8]
- 取值使用
- 普通对象
- 对象以键值对的形式存储数据。键也就是对象的属性,值就是一个具体的数据。属性的命名规则和变量命名规则有点相似,但是属性名更宽松。属性名允许是数字,不规范的属性名字可以加
" "
变成一个正确的属性名。let xz = {
name : “夏栀”,
“age” : 18, //属性可以加 “” 类似字符串的写法,也可以不加
“a b c” : true, //不规则的属性名,必须加 “”,不加会报错
20 : null //自然数数字可以充当属性名,不必加 “”
}; - 取值时使用
.
操作符。let xz = {
name : “夏栀”,
age : 18,
marry : false,
friends : [“锦鲤”,”思思”]
};
console.log( xz.age ); //18
console.log( xz.friends[0] ); //”锦鲤”
console.log( xz.hobby ); //undefined - 当属性是一个数据时,使用
[]
来取值let xz = {
name : “夏栀”,
age : 18,
marry : false,
friends : [“锦鲤”,”思思”]
};
console.log( xz.name ); //”夏栀”
console.log( xz[“name”] ); //”夏栀”
let a = “age”;
console.log( xz[a] ); //18
console.log( xz.a ); //undefined - 对象可以取值,也可以重新赋值,也可以新增属性let obj = {a : 10};
obj.a = 20;
obj.b = 30;
console.log(obj); // {a:20,b:30}
- 对象以键值对的形式存储数据。键也就是对象的属性,值就是一个具体的数据。属性的命名规则和变量命名规则有点相似,但是属性名更宽松。属性名允许是数字,不规范的属性名字可以加
- 内置对象JavaScript语法中本来已经存在的对象,称之为内置对象。这些对象一般都已经包含了很多属性和方法,功能健全丰富,我们可以直接哪来使用。例如
window
document
Math
。 - 函数JavaScript中函数也是对象类型,是一个极为特殊的对象。
- 定义函数let a = function(){
//这里可以写任意js代码
};
function b(){
//这里可以写任意js代码
} - 函数执行function fn(){
alert(123);
}
//函数不执行是,内部函数不会运行。
//函数加 () 可以自执行
fn(); - 更多函数相关的知识在后续章节会详细介绍
- 定义函数let a = function(){
object类型的数据,typeof
会得到object
,但是函数在typeof
时得到function
。