检测变量是否为原始值包装对象需三步:先判断 typeof 为 "object" 且非 null、非数组;再用 object.prototype.tostring.call 确认返回 "[object string]"、"[object number]" 或 "[object boolean]";最后验证 constructor 是否严格等于对应全局构造函数。

要检测一个变量是否为原始值的包装对象(比如 new String("a")、new Number(42)、new Boolean(true)),关键在于把它和原始值(如 "a"、42、true)明确区分开——它们在 typeof 中都看似“不同”,但仅靠 typeof 不够,必须组合判断。
看 typeof 是否为 "object" 且不是 null 或数组
包装对象的 typeof 结果恒为 "object",而原始值不会。但要注意:null、数组、普通对象也返回 "object",所以得先排除这些干扰:
-
typeof x === "object"是必要前提 -
x !== null排除 null -
!Array.isArray(x)排除数组
用 Object.prototype.toString.call 精确匹配包装类型标识
这个方法能返回标准的内部标签,对包装对象返回明确字符串:
-
Object.prototype.toString.call(new String("a"))→"[object String]" -
Object.prototype.toString.call(new Number(42))→"[object Number]" -
Object.prototype.toString.call(new Boolean(true))→"[object Boolean]"
只要结果是这三个之一,就基本可确认是对应包装对象(注意:Symbol 和 BigInt 也有包装类,但日常极少显式使用 new 创建)。
结合 constructor 判断是否由原生构造函数创建
包装对象的 constructor 指向其对应的全局构造函数,且未被篡改时是可靠的佐证:
-
new String("x").constructor === String→true -
new Number(1).constructor === Number→true -
new Boolean(false).constructor === Boolean→true
但需注意:原始值的 constructor 也指向相同构造函数(因隐式装箱),所以不能单独依赖它;必须与前两步配合使用。
避免只用 instanceof —— 跨 iframe 场景会失效
instanceof 对显式创建的包装对象有效:
-
new String("a") instanceof String→true -
"a" instanceof String→false
但它依赖原型链,在跨 iframe 或不同执行上下文时,String 构造函数可能不是同一个引用,导致误判。生产环境建议优先用 toString.call + constructor 组合。











