如何在JavaScript中判断目标是否为Class类?
当然有办法区分Class和普通函数!
你提到的情况确实很常见——因为ES6的class本质上是函数的语法糖,所以用typeof、instanceof这些常规检测手段都会把它识别成函数。不过别担心,我们可以利用class的专属特性来区分它们,下面给你几个实用的方法:
方法1:通过toString()方法判断
Class的toString()返回的字符串会以"class "开头,而普通函数的toString结果是以"function "开头的。直接看示例:
class yesClass { constructor () {} } function regularFunction() {} // 检测Class console.log(yesClass.toString().startsWith('class ')); // true // 检测普通函数 console.log(regularFunction.toString().startsWith('function ')); // true
这个方法简单直接,大部分场景下都能生效。
方法2:尝试直接调用(不加new)
普通函数可以直接执行,但Class如果不用new关键字调用会直接抛出错误。我们可以利用这个特性做检测:
function isClass(func) { try { func(); // 尝试直接调用 return false; // 能调用就是普通函数 } catch (e) { // 捕获到"必须用new调用"的错误就是Class return e.message.includes('cannot be invoked without \'new\''); } } console.log(isClass(yesClass)); // true console.log(isClass(regularFunction)); // false
不过要注意,如果普通函数内部本身就会抛出错误,这个方法可能会误判,所以结合其他方法使用更稳妥。
方法3:检测prototype上方法的可枚举性
Class内部定义的方法默认是不可枚举的,而普通函数添加到prototype上的方法默认是可枚举的。比如:
class yesClass { classMethod() {} } function regularFunction() {} regularFunction.prototype.funcMethod = function() {}; // Class的prototype上的方法不会被Object.keys枚举到 console.log(Object.keys(yesClass.prototype)); // [] // 普通函数的prototype方法会被枚举到 console.log(Object.keys(regularFunction.prototype)); // ["funcMethod"]
如果目标函数的prototype上有自定义方法,这个方法也能帮你区分。
为什么常规方法区分不了?
最后补充一下原因:在ECMAScript规范里,Class本身就是一种特殊的Function实例,所以typeof yesClass返回"function"、yesClass instanceof Function返回true都是符合规范的行为——它本质上还是函数,只是添加了一些语法层面的约束和特性而已。
内容的提问来源于stack exchange,提问作者Isitea
相关产品推荐
相关产品推荐

