JavaScript的数据类型
在JavaScript中,数据类型分为两大类:原始类型(Primitive Types)和引用类型(Reference Types) 。
原始类型(Primitive Types)
原始类型是最基本的数据类型,它们直接包含值。JavaScript有七种原始类型:
-
Undefined:表示变量未定义。
-
Null:表示空值。
-
Boolean:表示布尔值,只有两个取值:
true
和false
。 -
Number:表示数字,包括整数和浮点数。
-
BigInt:表示任意精度的整数。
-
String:表示字符串。
-
Symbol:表示唯一且不可变的标识符。
引用类型(Reference Types)
引用类型是对象类型,它们存储的是对值的引用,而不是值本身。
- Object JavaScript中最基本的引用类型,用于存储键值对。
- Array 表示有序集合,可以存储不同类型的值。
- Function JavaScript中函数也是对象,可以通过函数表达式或函数声明创建。
- RegExp 表示正则表达式,用于模式匹配。
- Date 用于处理日期和时间。
- 其他内置对象 包括
Map
,Set
,WeakMap
,WeakSet
,ArrayBuffer
,SharedArrayBuffer
,DataView
,Promise
等。
整理了一份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
类型判断
在一些项目场景中,我们需要用到类型判断,比如输入验证、多态处理等。在刚开始接触编程,我们用的最多的可能就是typeof了,但是,也还有其他方法适用于不同的场景。
typeof
如果我们试过,我们就会知道其实typeof有一些弊端
无法判断除function之外的引用类型
在JavaScript的早期版本中,只有五种数据类型: Undefined
、Null
、Boolean
、Number
和 String
。对象类型是后来加入的,包括 Object
和 Function
。 当时,JavaScript 的 typeof
操作符被设计为简单地返回这些基础类型的字符串表示。而对象类型的所有实例都被归类为 object
。这是因为在那时,对象类型还没有细分。
函数虽然也是对象的一种,但它们在JavaScript中具有非常特殊的地位和作用。函数不仅仅是数据容器,它们还具有可调用的特性,可以执行代码。因此,JavaScript设计者决定让 typeof
操作符对函数返回 'function'
,以便更明确地区分函数和其他对象。
可以判断除null之外的原始类型
为何null也是object呢?这其实是一个历史遗留问题,在JavaScript的最初版本中,使用的是32位系统,null
被表示为一个空的引用对象(即所有位都为0的对象指针),而typeof的判断原理是:将值转换为二进制后看其前三位是不是0 ,因此被错误地检测为对象类型。
instanceof()
instanceof
是JavaScript中的一个操作符,用于判断一个对象是否是另一个对象的实例。它在面向对象编程中非常有用,可以用来检查对象的类型,尤其是在继承关系中。
instanceof 如何判定的呢?
请大家思考一下,既然instanceof是用于判断一个对象是否是另一个对象的实例,那么,他是否是沿着原型链来判定的呢?
其实是的,instanceof的判定会沿着对象的原型链向上搜索,直到找到与构造函数的 prototype
属性严格相等的对象。如果找到,则返回 true
,否则返回 false
。
那么有人就会问了,原始类型不是有包装类吗?
只能判断引用类型
当我们访问一个原始类型的属性或调用一个方法时,JavaScript 会在后台创建一个临时的包装对象,允许我们像对象一样操作这些原始值。但是,这些包装对象是短暂的,并且在操作完成后会被销毁。instanceof
操作符检查的是对象的原型链,而不是值本身。当我们使用 instanceof
时,它检查的是对象的构造函数,而原始类型没有构造函数,所以 instanceof
对原始类型总是返回 false
。
手写myinstanceof
既然是沿着原型链,那我们是否可以来自己试试
js
复制代码
方法一:递归思路 function myinstanceof(L, R) { // 如果 L 是 null 或 undefined,直接返回 false if (L == null) return false; // 获取 L 的原型对象 let proto = Object.getPrototypeOf(L); // 递归地检查原型链 if (proto === R.prototype) { return true; } else if (proto === null) { return false; } else { return myinstanceof(proto, R); } } 方法二:while function myinstanceof(L, R) { // 如果 L 是 null 或 undefined,直接返回 false if (L == null) return false; // 获取 L 的原型对象 let proto = Object.getPrototypeOf(L); // 递归地检查原型链 while (proto !== null) { if (proto === R.prototype) { return true; } proto = Object.getPrototypeOf(proto); } return false; }
object.prototype.toString()
我想你没有想到吧,toString也可以吗? 是的 他也可以?
我们先来看看官方文档:
用我们强大的外语知识储备翻译就是这样的
lua
复制代码
1.如果toString接收的值是undefined,则返回"[object Undefined]" 2.如果toString接收的值是null,则返回"[object Null]" 3.调用 ToObject(x) 将x转为对象(这是内置方法) 此时得到的对象内部一定拥有一个属性[[class]],而该属性[[class]]的值就是x的类型 4.设 class是[[class]]的值 5.返回由"[object"和class 和"]" 拼接得到的字符串
如此可见,toString方法也可以的,但这是对象的一个,和其他类型的不同
- 数组的toString() 将数组中的元素用逗号的方式拼接成字符串
- 其他的toString() 直接将值修改成字符串字面量
那么问题来了,这是对象的,和其他的类型有啥关系呀?那就说明你没好好看这篇文章了
Object.prototype.toString
内部是通过 this
绑定来决定返回的类型字符串。当调用 Object.prototype.toString.call(value)
时,value
被传入并绑定为 this
,然后返回该值的内部 [[Class]]
属性表示的类型。每种类型的对象都有其内部的 [[Class]]
属性,这个属性决定了 Object.prototype.toString
返回的结果。
是的 我们可以用call方法来把this指向我们要判断的类型。
同时呢,我们可以实现一个通用类型判断函数
js
复制代码
function getType(value) { return Object.prototype.toString.call(value).slice(8, -1); } console.log(getType("hello")); // String console.log(getType(42)); // Number console.log(getType(true)); // Boolean console.log(getType(undefined)); // Undefined console.log(getType(null)); // Null console.log(getType(Symbol())); // Symbol console.log(getType(10n)); // BigInt console.log(getType([])); // Array console.log(getType({})); // Object console.log(getType(function(){})); // Function console.log(getType(/regex/)); // RegExp console.log(getType(new Date())); // Date console.log(getType(new Map())); // Map console.log(getType(new Set())); // Set console.log(getType(new WeakMap())); // WeakMap console.log(getType(new WeakSet())); // WeakSet console.log(getType(new Error())); // Error console.log(getType(new CustomType())); // Object
有没有和我一样,找到真爱了,哈哈哈