JavaScript 中的数据类型分为两大类
原始数据类型(Primitive Data Types)和引用数据类型(Reference Data Types)。以下是具体的种类:
原始数据类型
Number:表示整数和浮点数,例如 42, 3.14。
String:表示文本,例如 "Hello, World!"。
Boolean:逻辑值,只有 true 和 false 两个值。
Undefined:表示变量已被声明但尚未被赋予任何值。
Null:表示一个刻意的空值或缺少值,它只有一个值 null。
Symbol(ES6 新增):符号类型,是唯一且不可变的值,常用于对象的键,以避免键名的冲突。
BigInt(ES10 新增):可以安全地存储、操作大整数,超过 Number.MAX_SAFE_INTEGER 的整数。
引用数据类型
Object:复合数据类型,可以包含多个键值对,包括数组(Array)、函数(Function)、日期(Date)、正则表达式(RegExp)等都是基于对象的。
Function:函数本身也是一种对象,可以作为值来传递和赋值。
Array:特殊类型的对象,用于存储有序的元素集合。
Date:用于处理日期和时间。
RegExp:正则表达式对象,用于匹配字符串中的模式。
Map, Set, WeakMap, WeakSet(ES6 新增):这些是新的集合类型,提供了更灵活的数据结构。
Promise(ES6 新增):用于异步计算。
Buffer(Node.js 特有):处理二进制数据。
Error:错误对象,用于表示程序运行时发生的错误。
Class(ES6 新增):用于实现面向对象编程中的类。
每种数据类型都有其特定的用途和操作方式,理解它们的特性对于编写高效、可靠的JavaScript代码至关重要。
判断方法
typeof
- 可以判断除了
null
以外的所有原始类型 - 无法判断除了
function
以外的所有引用类型
typeof
的判断原理是:将之转换为二进制后看其前三位是不是0, 除了函数function
,所有的引用类型的二进制前三位都是0,而null的二进制是000000000
- 基本数据类型检测 :
- 对于原始数据类型(如
number
、string
、boolean
、undefined
、symbol
(ES6引入)、bigint
(ES10引入)),typeof
会直接返回其类型名称(如"number"
、"string"
等)。 - 而对于
undefined
,它会返回"undefined"
。
- 对于原始数据类型(如
- 对象和数组检测 :
- 对于对象(包括普通对象、数组、函数等),
typeof
一律返回"object"
。注意,尽管函数是一种特殊的对象,但使用typeof
检查函数时,会返回"function"
,这是typeof
的一个特例。
- 对于对象(包括普通对象、数组、函数等),
- null值的特殊性 :
- 对于
null
值,typeof
会返回"object"
,这是一个历史遗留问题,通常被认为是JavaScript的一个设计缺陷。
- 对于
- 示例:
js
console.log(typeof 42); // 输出: "number"
console.log(typeof "Hello"); // 输出: "string"
console.log(typeof true); // 输出: "boolean"
console.log(typeof undefined); // 输出: "undefined"
console.log(typeof Symbol()); // 输出: "symbol"
console.log(typeof BigInt(42)); // 输出: "bigint"
console.log(typeof {}); // 输出: "object"
console.log(typeof []); // 输出: "object"
console.log(typeof function(){}); // 输出: "function"
console.log(typeof null); // 输出: "object"
构造个函数专门来判断是否为对象
通过typeof
方法可判断输入的是否为对象,还要小心不能为null
js
function isObject(obj){
if(typeof obj === 'object' && obj !== null){
return true
}else{
return false
}
}
console.log(isObject({}));//ture
instanceof
- 只能用来判断引用类型
- 通过原型链的查找来判断
- 基本数据类型检测 :
- 对于原始数据类型
instanceof
会直接返回flase
- 而对于
undefined
,它会直接报错。
- 对于原始数据类型
- 对象检测 :
- 对于对象(包括普通对象、数组、函数等),
instanceof
在判断完是否正确后返回ture
。 - 而
数组(Array)、函数(Function)、日期(Date)、正则表达式(RegExp)
等都是基于对象的,通过查找到原型链,最后都能找到Object
上,因此instanceof
在判断以上内容时可以成功判定为Object
- 对于对象(包括普通对象、数组、函数等),
js
let str = 'str'
let num = 1
let flat = true
let un = undefined
let nu = null
let obj = {}
let arr = []
let func = function(){}
let date = new Date()
console.log(str instanceof String); // false
console.log(num instanceof Number); // false
console.log(flat instanceof Boolean); // false
console.log(un instanceof undefined); //报错,后面必须是大写即构造函数
console.log(obj instanceof Object);// true
console.log(arr instanceof Array);// true
console.log(func instanceof Function);// true
console.log(arr instanceof Object);// true
手搓一个与之作用相当的函数
即判断左边的隐式原型是否与对应右边的显式原型相等
js
function myInstanceof(L,R) {
while(L !== null){
if(L.__proto__ === R.prototype){
return true
}
L = L.__proto__
}
return false
}
var arr = []
console.log(myInstanceof(arr, Array));// true
Object.prototype.toString()
先来回忆一下toString()
方法
- 对象的toString()
- 数组的toString():将数组中的每个元素都转换为字符串,然后用逗号拼接起来
- 其他的toString():直接将值修改为字符串字面量
开发者可以自定义对象的 toString()
方法
js
let person = {
firstName: "John",
lastName: "Doe",
toString: function() {
return this.firstName + " " + this.lastName;
}
};
console.log(person.toString()); // 输出: "John Doe"
数组的toString()
js
let array = [1, 2, 3];
console.log(array.toString()); // 输出: "1,2,3"
函数的toString()
js
function sayHello(name) {
return "Hello, " + name + "!";
}
console.log(sayHello.toString());
// 输出可能为: "function sayHello(name) {\n return \"Hello, \" + name + \"!\";\n}"
Object.prototype.toString(x)
- 如果 toString() 接受的值是 undefined则返回 [object Undefined]
- 如果 toString() 接受的值是 null则返回[object Null]
- 调用 ToObject(x) 将x转为对象,此时得到的对象内部一定拥有一个属性:[[Class]],该属性[[Class]]的值就是x的类型。
- 设,class 是[[Class]]的值
- 返回由"[object ", class, and "]"拼接组成的字符串
基本用法
当你直接调用toString()
方法在一个对象上调用时,如果没有被覆盖,它会返回一个表示该对象的字符串。但是,直接使用toString()
可能会因为对象自定义了toString
方法而得到非预期的结果。因此,推荐使用Object.prototype.toString.call()
或Object.prototype.toString.apply()
来避免这种情况,确保总是调用到原始的toString
实现。
js
let array = [1, 2, 3];
console.log(array.toString()); // 输出: "1,2,3"
console.log(Object.prototype.toString.call(array)); // 输出: "[object Array]"
返回格式
对于大多数内置对象,Object.prototype.toString.call()
会返回一个形如"[object Type]"
的字符串,其中Type
是对象类型的一个小写形式描述。例如:
- 数组:
[object Array]
- 字符串:
[object String]
- 布尔值:
[object Boolean]
- 数字:
[object Number]
- 空对象:
[object Object]
- 函数:
[object Function]
- 正则表达式:
[object RegExp]
- 日期:
[object Date]
Error
对象:[object Error]
Map
:[object Map]
Set
:[object Set]
WeakMap
:[object WeakMap]
- 等等
示例
js
javascript
console.log(Object.prototype.toString.call([])); // 输出: "[object Array]"
console.log(Object.prototype.toString.call(new Date)); // 输出: "[object Date]"
console.log(Object.prototype.toString.call(/abc/)); // 输出: "[object RegExp]"
创建一个函数来直接输出该输入的类型种类
在Object.prototype.toString.call()
会返回一个形如"[object Type]"
的字符串,而这里我们只需要得到object
后的数据,于是可直接使用slice方法
删去不需要的数据
js
function type(x) {
let res = Object.prototype.toString.call(x);// [object String]
return res.slice(8, res.length-1);// String
//return res.slice(8, -1)
}
type('asdfg')// String
type(123)// Number
type([])// Array
console.log(type(123));
作为类型检查工具
由于其能提供精确的类型信息,Object.prototype.toString.call()
常被用作一个强大的类型检查工具,特别是在需要区分数组、正则表达式等特殊对象类型时。
Array.isArray()
只能判断数组,ture false
js
let arr = [];
console.log(Array.isArray(arr)); // 输出: true
总结
首先我们需要知道JavaScript中数据类型分为两大类原始数据类型和引用数据类型,接着可以使用许多方法来判断其中的具体类型。
typeof
可以判断除了null以外的所有原始类型,无法判断除了function以外的所有引用类型,直接输出类名instanceof
只能用来判断引用类型,输出ture or false
Array.isArray()
只能判断数组,输出ture or false
Object.prototype.toString()
是最为全面的判断方法,用它就没错,输出[object 类型名]