JavaScript 是一种动态弱类型的语言,变量被赋值时可以自动推断其类型,这在一定程度上方便了开发,但同时也可能导致一些类型相关的问题。为了解决这些问题,我们需要使用 JavaScript 中的类型判断方法。今天我们将详细讲解各种方法和使用它们需要注意的问题。
数据类型
先来回顾一下数据类型:
- 原始类型:
- number数值型: let num = 123
- string字符串:let str = 'hello'
- boolean布尔型:let bool = true
- undefined未定义: let un = undefined
- null空值:let nl = null
在es6后,还新增了两种原始类型:
6. Symbol类型:let s = Symbol(123)
它表示一个独一无二的值,可以用作对象属性的键。Symbol值是不可变且唯一的,每个Symbol值都是独立的,不会和其他任何值相等。
创建Symbol可以使用Symbol()构造函数或Symbol.for()方法。Symbol()构造函数创建的Symbol是临时的,而Symbol.for()方法创建的Symbol是全局的,它会先在全局Symbol注册表中搜索键为传入参数的Symbol,如果找到则返回该Symbol,否则创建一个新的Symbol并添加到全局Symbol注册表中。
Symbol可以作为对象的属性键,用于解决属性名冲突的问题。由于每个Symbol值都是唯一的,所以可以保证不会与其他属性名冲突。例如:
ini
const mySymbol = Symbol();
const obj = {};
obj[mySymbol] = 'Hello Symbol';
console.log(obj[mySymbol]); // 输出 'Hello Symbol'
需要注意的是,Symbol值并不具有字符串的隐式转换功能,如果需要显示转换为字符串,可以使用Symbol的toString()方法或将其与一个空字符串进行连接。
7. BigInt大整型:let big = 123n
BigInt类型用于存储超出JavaScript固有数字限制的大整数。JavaScript中的Number类型可以精确表示最大值为2^53-1的整数值,超过这个值的整数计算可能会产生精度丢失。而BigInt类型则可以表示任意大的整数,不受JavaScript固有数字限制的影响。
使用BigInt类型可以通过在整数值后面加上n来创建,例如:const bigNum = 123456789012345678901234567890n;
BigInt类型支持包括加减乘除、位运算等在内的多种算术运算和比较操作。需要注意的是,在进行数值运算时,BigInt类型只能与其他BigInt类型进行运算,不能与普通Number类型混合运算。
例如,可以使用以下代码创建两个BigInt类型的变量并进行加法运算:
ini
const bigNum1 = 123456789012345678901234567890n;
const bigNum2 = 987654321098765432109876543210n;
const result = bigNum1 + bigNum2;
console.log(result);
- 引用类型:
- Object对象:let obj = {}
- Function函数:let fn = function(){}
- Array数组:let arr = []
- Date日期:let date = new Date()
(本文类型判断中引用类型就只讨论这几种,还有其他正则表达式等就不提了)
类型判断
接下来我们进入正题,类型判断有哪几种方法呢?
1. typeof
用typeof进行类型判断,需要注意以下两点:
-
typeof可以准确判定原始类型,除了null,用typeof判断null会输出object。
-
typeof不能判定引用类型,除了function,用typeof判断引用类型都会输出object,但除了function,function类型它可以判断出来。
javascriptconsole.log(typeof 'hello'); console.log(typeof 123); console.log(typeof true); console.log(typeof undefined); console.log(typeof Symbol(1)); console.log(typeof 123n); console.log(typeof null); console.log(typeof ({})); //object console.log(typeof ([])); //object console.log(typeof (new Date())); //object console.log(typeof (function(){})); //function
输出结果是:

2. instanceof
使用instanceof运算符来判断是否是某种类型需要知道的是:
-
只能判断引用类型,当我们用instanceof去判断原始类型时,输出值一律为false。
-
instanceof的原理是通过原型链的查找来判断的。所以当我们去判断数组、函数、日期类型是否为对象类型时,也会返回true。
javascriptlet str = 'hello' console.log(str instanceof String); //不能判断,专门为引用类型打造的 let obj = {} let arr = [1,3] let date = new Date() let fn = function(){} console.log(obj instanceof Object); console.log(arr instanceof Array); console.log(date instanceof Date); console.log(fn instanceof Function); console.log(arr instanceof Object);// 输出true
输出结果为:

我们来看一下instanceof的原理,如果有对原型链不太懂的掘友可以先去看下我这篇 JavaScript原型与原型链:理解核心概念,构建强大的前端技能哦,里面有详细讲解。
在JavaScript中,每个对象都有一个原型(prototype),原型又是一个对象,同时也有自己的原型。这样形成了一个原型链,直到最顶层的原型为null。
instanceof操作符会检查对象的原型链,看是否能在链上找到与指定构造函数的原型相匹配的原型。
如果在原型链中找到了匹配的原型,instanceof返回true;如果顺着原型链一直往上找到null都没有找到匹配的原型,则返回false。
javascript
//instanceof 的原理
function myInstance(l,r){
let left = l.__proto__
let right = r.prototype
while(left !== null){
if(left === right){
return true
}
left = left.__proto__
}
return false
}
3. Object.prototype.toString()
Object.prototype.toString() 方法是 JavaScript 中最古老的方法之一,它可以比较准确地判断一个值的类型,包括原始类型和对象类型。当我们调用 Object.prototype.toString() 方法时,会根据传入的值的 [[Class]] 内部属性的值返回一个形如 "[object class]" 的字符串,其中 class 是实际类型的字符串表示。
typescript
let str = 'hello'
let num = 123
let bigint = 123n
let obj = {}
let arr = [1,2]
console.log(Object.prototype.toString.call(str));
console.log(Object.prototype.toString.call(num));
console.log(Object.prototype.toString.call(bigint));
console.log(Object.prototype.toString.call(obj));
console.log(Object.prototype.toString.call(arr));
输出结果为:

需要注意的是,Object.prototype.toString() 方法返回的是一个形如 "[object class]" 的字符串,我们可以通过对返回结果进行处理来判断类型,将返回结果进行字符串切割。以代码里的str = 'hello'
为例:
vbnet
console.log(Object.prototype.toString.call(str).slice(8,-1));
// 进行切割后将由输出[object String]变为输出String
如果想要详细了解这个方法的原理,可以点此15.2.4.2Object.prototype.toString ( )官方文档里去查看。
4. Array.isArray()
Array.isArray() 方法用于判断一个值是否为数组类型,它只能用于数组类型的判断,对于其他引用类型则返回 false。
以下是使用 Array.isArray() 方法进行数组类型判断的示例代码:
ini
let arr = [];
console.log(Array.isArray(arr)); // 输出 true
需要注意的是,Array.isArray() 方法位于 Array 对象上,而不是在它的原型上,因此我们可以直接调用该方法来进行数组类型的判断,但不能arr.isArray()
这样去用。
今天类型判断的方法到这就讲完啦!欢迎下次再来一起学习哦ヾ(◍°∇°◍)ノ゙