判断js对象类型的方法
概述
js判断对象类型基本就是四种方法:
- typeof
- instanceof
- constructor.name
- Object.prototype.toString
各种方法的原理和优劣可以看判断JS数据类型的四种方法 - 一像素 - 博客园 (cnblogs.com),本文主要介绍其中最准确的方法Object.prototype.toString
得到对象类型方法
let x = []
console.log(Object.prototype.toString.call(x)) // [object Array]
Object.prototype.toString 方法是检测对象类型的一种标准方式,因为它能够返回一个清晰、一致的表示对象类型的字符串。对于标准内建对象,这个方法返回的字符串遵循 "[object Xxx]" 的格式,其中 Xxx 就是对象的类型。
方法原理
当你调用 Object.prototype.toString.call(new Date())
时,这个方法会读取调用它的对象的内部 [[Class]]
属性来确定对象的类型。对于不同类型的对象,[[Class]]
属性有不同的值,比如对于一个日期对象(Date 实例),[[Class]]
的值是 Date
。因此,当你对一个 Date 实例调用 Object.prototype.toString
方法时,它会返回字符串 [object Date]
。
在ECMAScript规范中,[[Class]] 是一个内部属性,它不直接暴露给开发者。
自定义对象配置
我看到有部分文章说Object.prototype.toString
方法的缺点是自定义的对象无法使用这种方法获取到类型,只能拿到[object Object]
,这是不正确的。我们可以通过配置自定义对象的Symbol.toStringTag
属性值来使得Object.prototype.toString
正确打印出自定义对象的类型值。
class X {
// 使用getter定义Symbol.toStringTag
get [Symbol.toStringTag]() {
return 'X';
}
}
let x = new X();
console.log(Object.prototype.toString.call(x)); // 输出:'[object X]'
总结
- js获取对象类型最准确的方法是通过借调
Object.prototype.toString
,例如Object.prototype.toString.call(x)
; - 自定义对象也可以通过配置对象的
Symbol.toStringTag
属性,使得自定义对象的实例也可通过借调Object.prototype.toString
来获取到对象类型; - js内置对象没有配置
Symbol.toStringTag
属性,而是使用了内置隐藏属性[[Class]]
来保存当前对象类型,其同样可以通过借调Object.prototype.toString
打印出来。
对instanceof的补充
instanceof
是通过判断左侧对象的__proto__
属性所指的原型对象是否在右侧“类”的prototype
属性所指的原型链上,来判断左侧对象是否为右侧“类”的实例。
但是在iframe中,不论是父页面通过直接拿到contentWindow来拿到子窗体进而拿到对象,还是子页面通过window.parent/window.top进而拿到父窗体进而拿到对象,拿到的对象使用instanceof一定是false的。如下所示:
// 父页面
window.onload = function () {
var iframe = document.getElementById("childFrame");
var childWindow = iframe.contentWindow;
var childArray = childWindow.childArray;
// 尝试在父页面中检查这个数组是否是Array的实例
console.log("childWindow.childArray", childArray instanceof Array); // 这里会输出false
};
// 子页面
var childArray = [1, 2, 3];
这是因为JavaScript在不同的全局执行环境(如不同的iframe或窗口)中,会为每个环境创建一套独立的内置对象,包括Array、Object等。即便这些iframe或窗口来自同一个源,它们的全局执行环境也是隔离的。这意味着来自不同iframe的对象实例,即使它们的构造函数看似相同(比如都是Array),也被认为是不同的,因为它们分别属于不同的全局执行环境。