JavaScript 中的类型判断
在 JavaScript 中,类型判断是我们经常需要处理的问题之一。由于 JavaScript 是一种动态类型语言,变量的类型可能在运行时改变,这使得类型判断变得更加复杂。本文将介绍 JavaScript 中常见的类型判断方法,并提供一些示例来帮助您更好地理解。
1. 使用 typeof 运算符
typeof
是 JavaScript 中用于检测变量类型的一种常用方法。它返回一个表示变量类型的字符串。常见的类型包括 "undefined"
、"boolean"
、"number"
、"string"
、"object"
和 "function"
。
javascript
javascriptCopy code
console.log(typeof undefined); // "undefined"
console.log(typeof true); // "boolean"
console.log(typeof 42); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof {}); // "object"
console.log(typeof function(){}); // "function"
需要注意的是,typeof null
返回 "object"
,这是 JavaScript 中的一个历史遗留问题。
2. 使用 instanceof 运算符
instanceof
运算符用于检查对象是否属于某个特定的类型,或者是否是该类型的子类的实例。它的语法是 object instanceof constructor
,如果 object
是 constructor
的实例,则返回 true
,否则返回 false
。
javascript
javascriptCopy code
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(42 instanceof Number); // false
console.log("hello" instanceof String); // false
需要注意的是,instanceof
运算符只能用于检查对象的类型,不能用于基本类型的检查。
3. 使用 Object.prototype.toString.call()
Object.prototype.toString.call()
方法是一种更加可靠和灵活的类型检测方法。它可以检测任何 JavaScript 对象的类型,包括基本类型和引用类型。
javascript
javascriptCopy code
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
console.log(Object.prototype.toString.call(42)); // "[object Number]"
console.log(Object.prototype.toString.call("hello")); // "[object String]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call(function(){})); // "[object Function]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
在使用Object.prototype.toString.call()
的时候,我们先来了解一些东西,方便我们对这个方法理解更加透彻。
首先
我们先来了解一下call()
函数的作用和内部逻辑,首先我来介绍一下call()
的作用。
javascript
let obj = {
var a = 1
}
function foo() {
console.log(this.a)
}
console.log(foo.call(obj))// 输出结果为1
它的作用就是显示绑定this到你选择的对象上,其实我们可以用自己的办法来写一个类似于call()
方法。
javascript
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') {
throw new TypeError('myCall is not a function');
}
let args = [...arguments].slice(1) // Array.from(arguments).slice(1)
context.fn = this
let res = context.fn(...args) // 触发this隐式绑定规则
delete context.fn
return res
}
我们来解析一下这段代码:
第2行上的typeof this !== 'function'
这就是判断调用方法的对象它是不是函数,如果不是的话就抛出错误,如果是的话就继续下一步。(ps:有些人不理解this
指的是什么,你可以去看下这篇文章小白自学:js中的一座this大山,真的难 - 掘金 (juejin.cn),它指代的是你需要绑定的函数,也就是上面代码中的foo.call(obj)
中的foo
)
第5行不用理会,它就是一个切片后赋值。
第7行代码就是比较重要的了,我们将形参也就是传进来的对象赋予一个fn
属性,这个属性值就是this
,也就是指向你需要绑定的函数。
第8行代码就是执行绑定的函数this
,第9行和第10行代码就是删掉对象context
中的fn
属性,并且返回它,这是因为call()
方法绑定的this
,并不会改变原来的实例对象。
好了大家对于call()
都有一定的了解了,现在就是来理解call()
前面为什么会有Object.prototype.toString
了。
然后
javascript
console.log(Object.prototype.toString(123))
console.log(Object.prototype.toString())
console.log(Object.prototype.toString.call(123))
大家看下上面这段代码,你们觉得它输出什么呢?
答案就是:[Object Object]
、[Object Object]
和[Object Number]
!
为什么前面两个都是一样的呢?因为这一段代码中就有个错误,toStarting()
这不是类型转换吗?这个括号里面是没有参数传入的,现在我们加入call()
就可以很好的理解了。
我们将Object.prototype.toString
看成需要绑定的一个方法,于是我们可以知道这段代码的意思就是:传入的对象的隐式原型等于它构造函数的显示原型,也就是这个对象的类型。(ps:如果大家对于原型的理解还不够深入的话,可以看下这篇文章小白自学:js中让人头大的原型 - 掘金 (juejin.cn))
现在我们就讲清楚了这段代码的详情,这个部分也是经常遇到的面试题。
4. 使用 Array.isArray()
如果要检测一个值是否为数组,可以使用 Array.isArray()
方法。它会返回一个布尔值,表示传入的值是否为数组。
javascript
javascriptCopy code
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray(42)); // false
5. 总结
类型判断在 JavaScript 中是非常常见的操作,我们可以使用 typeof
、instanceof
、Object.prototype.toString.call()
和 Array.isArray()
等方法进行类型判断。在实际应用中,根据具体的需求和场景选择合适的方法来进行类型判断是非常重要的。