一、js的数据类型
本文将介绍 JavaScript 的 8 种数据类型,结合代码对每种数据类型进行总结归纳。
1.基本数据类型
- Undefined:未定义型 一个变量声明了但是未赋值的情况下就是undefined;
- Null:空型 一般用来清空变量,也起了占位作用
- String:字符型 凡是被双引号或单引号包裹起来的都叫做字符型,字符串有length属性。
- Number:数值型 包含整数和浮点数(浮点数数值必须包含一个小数点,且小数点后面至少有一位数字)两种值。 (1)
NaN:非数字类型。 特点:①涉及到的任何关于NaN的操作,都会返回NaN ② NaN不等于自身。 (2)isNaN():用于检查其参数是不是数值,得到的结果是一个布尔值,不是数值返回true,是数值返回false。 - Boolean:布尔型,只有true和false两个值。
- Symbol:代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
- BigInt:是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数已经超出了Number能够表示的安全整数范围。
2.引用数据类型
- Object:表示键值对的集合,是 JavaScript 中所有对象的基础。除了基本数据类型之外的所有类型都是对象类型,这包括:
Array:表示元素的有序集合。
Function:表示函数。
Date:表示日期和时间。
RegExp:表示正则表达式。
其他内置对象,如 Map、Set、WeakMap、WeakSet 等以及用户自定义类型。
二、基本数据类型和引用数据类型的特点
1.基本数据类型
- 基本数据类型的值直接存储在栈内存中,占据空间小、大小固定。
- 基本类型类型的值被赋给另一个变量时,实际上是创建了该值的一个副本,两个变量分别持有各自的值,其中任一变量的值修改不会影响到另一个变量的值
- 比较基本数据类型时,是比较它们的值是否相等
let name="abc";
let age=18;
// 赋值
let a=18;
let b=a;
a=456;
console.log(b); // 18
console.log(a); // 456
// 比较
console.log(a === b) // false
console.log(age === b) // true
存储结构如下:
| 栈 | |
|---|---|
| name | abc |
栈区中包含了变量的变量的标识符和变量的值
2.引用数据类型
- 引用数据类型的值存储在堆内存中,占据空间大,大小不固定。当创建一个引用类型的变量时,栈内存中只会存储指向堆内存中实际数据的引用地址,而不是数据本身。
- 引用数据类型赋值是按引用进行的,当把一个引用类型的值赋给另一个变量时,实际上是复制了引用,两个变量指向同一个对象,对其中一个的修改会影响另一个
- 比较引用数据类型时,是比较它们的引用是否指向相同的内存地址。
let obj={
name:"abc",
age:18,
}
// 赋值
let obj2=obj;
obj2.name="def";
console.log(obj.name); // def
// 比较
let name="abc";
console.log(obj.name===name) // false
console.log(obj.name==obj2.name) // true
存储结构如下:
| 栈 | |
|---|---|
| name | abc |
| 堆 | |
|---|---|
| obj |
堆中存的是实体的地址,栈中存的是一个指向堆内存的引用
三、js的类型判断的方法
1.使用typeof操作符
typeof操作符可以用来检测基本数据类型,比如字符串、数字、布尔值、函数等,但对于对象和数组的区分不够准确。- 优点:简单快捷,适用于基本数据类型(如字符串、数字、布尔值)和函数的判断。缺点:对于对象类型的判断不够准确,无法区分数组和对象,null 被识别为 "object"(这是一个历史遗留问题)。
console.log(typeof "Hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof function(){}); // "function"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof null); // "object" (注意:null被错误地归类为"object")
console.log(typeof undefined); // "undefined"
2.使用instanceof操作符
instanceof操作符用于检测对象的构造函数,可以判断一个对象是否是某个特定类型的实例。- 优点:可以精确判断对象是否属于指定的构造函数。缺点:在多个全局执行环境或框架中使用时可能会出现问题,不适用于原始数据类型的判断。
let arr = [];
console.log(arr instanceof Array); // true
let obj = {};
console.log(obj instanceof Object); // true
3.使用Array.isArray()方法
Array.isArray()方法专门用于检测一个对象是否为数组。- 优点:精确判断一个对象是否为数组。缺点:在某些较旧的浏览器版本中可能不被支持。
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
let obj = {};
console.log(Array.isArray(obj)); // false
4.使用Object.prototype.toString.call()
- 这是一种通用且精确的方法,可以判断任意数据类型。
- 优点:通用且精确,适用于所有数据类型的判断。缺点:语法稍显复杂,需要使用较长的表达式。
console.log(Object.prototype.toString.call("Hello")); // "[object String]"
console.log(Object.prototype.toString.call(50)); // "[object Number]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]
5.使用constructor
- 在定义一个函数(构造函数)的时候,JS引擎会为其添加
prototype原型,原型上有其对应的constructor属性指向该构造函数,从而原型和构造函数之间互相知道对方。当构造函数实例化的时候,会产生对应的实例,其实例可以访问对应原型上的constructor属性,这样该实例就可以了解到通过谁产生了自己,这样就可以在新对象产生之后了解其数据类型。 constructor方法虽然该方法可以判断其数据类型,但存在两个缺点:1.null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据需要通过其他方式来判断。2.函数的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor引用会丢失,constructor会默认为Object
const val1 = 1;
console.log(val1.constructor); // [Function: Number]
const val2 = 'abc';
、uctor); // [Function: String]
const val3 = true;
console.log(val3.constructor); // [Function: Boolean]
四、类型转换
分为两类:隐式类型转换和显式类型转换。
1.显示类型转型
显示类型转换是开发人员手动执行的类型转换操作,通过一些内置函数或操作符实现。在强制类型转换中,开发人员明确地指定要将值转换为的目标类型。常见的强制类型转换方式包括:
- 使用
Number()或parseInt(value)或parseFloat(value)函数将值转换为数字类型。 - 使用
String()函数将值转换为字符串类型。 - 使用
Boolean()函数将值转换为布尔类型。
let num = "123";
let str = String(num); // "123"
let int = Number(str); // 123
let bool = Boolean(int); // true
console.log(typeof str); // string
console.log(typeof int); // number
console.log(typeof bool); // boolean
2.显示类型转换
这是 JavaScript 自动执行的类型转换,通常发生在表达式中,当运算符或方法需要不同类型的参数时。例如
- 加法运算符(
+):用于将数字、字符串和其他类型相加时进行隐式类型转换。 - 比较运算符(
==和!=):在使用相等和不相等运算符时,JavaScript 会根据需要自动进行类型转换,比较两个值是否相等。 - 逻辑运算符(
&&和||):逻辑与(&&)和逻辑或(||)也可以进行隐式类型转换,将操作数转换为布尔值并返回原始值。 - 三元条件运算符(
?:):用于条件判断时,也会触发隐式类型转换以满足条件表达式的要求。
// 字符串与数字相加:
const result = "10" + 5;
// 在这里,数字 5 被隐式转换为字符串 "5",然后与字符串 "10" 进行拼接,结果为字符串 "105"
// 数字和布尔值的运算:
const result1 = 10 - true;
// 在这里,布尔值 true 被转换为数字 1,然后与数字 10 进行减法运算,结果为数字 9
// 逻辑运算中的隐式类型转换:
Codeif (2) {
// 2 被隐式转换为 true
}
// 比较运算中的隐式类型转换:
const isEqual = "10" == 10;
// 在比较时,字符串 "10" 被隐式转换为数字 10,然后进行比较