上一篇中我们介绍了ES6新增的两种原始数据类型,BigInt 和 Symbol,并且介绍了一种判断类型的方法------typeof。如果你对它们不太熟悉的话,建议您返回我的ES6 中新增的两种数据类型及类型判断 ( 一 )文章,再继续本文的阅读。如果您觉得我的内容对您有所帮助或是启发的话,可以给我一个赞赞作为鼓励。之后我会持续更新有关于JS干货知识点。
前言
这篇文章我们来聊聊另外三种可以判断数据类型的方法,它们分别是
- Array.isArray(arr)
- Object.prototype.toString.call(xxx)
- instanceof
在这三个方法中,第三种方法instanceof
在面试时,面试官可能会要求我们自己手写一个instanceof
方法去判断函数类型,接下来我也会带大家一起写一下。
Array.isArray(arr)
Array.isArray(arr)
是 JavaScript 中用于检查一个变量是否为数组的方法。这个方法返回一个布尔值,如果变量是数组,则返回 true
;否则返回 false
。
我们来一个 Array.isArray
的使用示例:
js
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // 输出 true
let notArray = "This is not an array";
console.log(Array.isArray(notArray)); // 输出 false
let alsoNotArray = { key: "value" };
console.log(Array.isArray(alsoNotArray)); // 输出 false
当处理变量时,特别是在处理函数参数或其他可能具有不同数据类型的情况下,我们希望在使用数组相关方法之前先检查变量是否是一个数组。这就是 Array.isArray
很有用的地方。例如:
js
function processArray(input) {
if (Array.isArray(input)) {
// 如果输入是数组,进行数组相关的操作
for (let i = 0; i < input.length; i++) {
console.log(input[i]);
}
} else {
// 如果输入不是数组,给出一个警告或采取其他适当的操作
console.log("Input is not an array!");
}
}
let myArray = [1, 2, 3];
let notAnArray = "Hello";
processArray(myArray); // 输出数组元素
processArray(notAnArray); // 输出警告信息
在这个例子中,processArray
函数接受一个参数 input
,并在处理之前检查它是否是数组。如果是数组,就可以安全地使用数组相关的操作,否则会给出一个警告。这有助于确保代码在期望接收数组时不会由于传递了其他类型的参数而导致错误。
Object.prototype.toString.call(xxx)
Object.prototype.toString.call(xxx)
这个语法的目的是为了获取 xxx
的准确类型信息,以此来判断类型
-
Object.prototype.toString
: 这是一个引用了Object
原型上的toString
方法的表达式。这个方法的主要作用是返回一个字符串,其中包含了对象的内部[[Class]]
属性,表示对象的类型。这个方法通常是被重写的,以提供更具体的信息。 -
call(xxx)
:call
是 JavaScript 中函数对象的一个方法,它允许你调用一个函数并指定函数内部的this
值。在这个语法中,我们将Object.prototype.toString
这个方法作为函数调用,同时将xxx
作为上下文(即this
的值)传递给这个方法。当我们使用
Object.prototype.toString.call(xxx)
时,实际上是在将xxx
传递给toString
方法,这样就能够获取xxx
的准确类型信息。
js
let myArray = [1, 2, 3];
let myObject = { key: 'value' };
console.log(Object.prototype.toString.call(myArray)); // 输出: [object Array]
console.log(Object.prototype.toString.call(myObject)); // 输出: [object Object]
在这个例子中,Object.prototype.toString.call(myArray)
返回 "[object Array]"
,表示 myArray
是一个数组。
而 Object.prototype.toString.call(myObject)
返回 "[object Object]"
,表示 myObject
是一个普通的对象。
注意,直接使用 toString
方法可能会返回不同的结果:
js
console.log(myArray.toString()); // 输出: 1,2,3
console.log(myObject.toString()); // 输出: [object Object]
instanceof
- 只能判断引用类型
- 且是通过原型链查找来判断的
让我们先来定义一些数据变量:
js
let obj = {}
let arr = []
let fn = function () {}
let date = new Date() //Date
我们用instanceof
来判断一下:
js
console.log(obj instanceof Object); // true
console.log(arr instanceof Array); // true Object) // true
console.log(fn instanceof Function); // true
console.log(date instanceof Date); // true
我们可以看出,insantceof
可以准确的判断出引用数据类型,但是,如果arr instanceof Object
,会输出什么呢?
js
console.log(arr instanceof Object) // true
这是为什么呢?
因为instanceof
的底层逻辑是顺着原型链向上查找,因为arr
也是一个特殊的对象,顺着原型链最终会查找到Object
,所以会打印为true
。
我们可以手写一份instanceof
,同样这也是面试时时常出现的考题:
js
function instancOF(L, R) {
let left = L.__proto__
let right = R.prototype
while (left !== null) {
if (left === right) return true
left = left.__proto__
}
return false
}
console.log(instancOF([], Array)); // true
console.log(instancOF([], Object) ); // true
这个伪代码版本演示了 instanceof
的基本原理:
- 通过
L.__proto__
获取对象的原型。 - 沿着原型链遍历,检查每个原型是否等于指定构造函数的原型。
- 如果找到匹配的构造函数的原型,返回
true
。 - 如果遍历完整个原型链都没有找到匹配的构造函数的原型,返回
false
。
今天的内容就到这啦,如果你觉得小编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧