JavaScript中字符串字面量与String对象的类型差异疑问
为什么字符串字面量和String对象的typeof结果不同,但Object.prototype.toString.call()结果一致?
这是个非常典型的JavaScript类型系统问题,我来给你一步步拆解清楚~
先看你给出的代码,格式化后更清晰:
var a = new String( "aaaa" ); var b='adddd'; console.log(a) // String('aaaa') console.log(b) // adddd console.log(typeof a) // object console.log(typeof b) // string console.log(Object.prototype.toString.call( a )) // [object String] console.log(Object.prototype.toString.call( b )) // [object String]
1. 为什么typeof的结果不一样?
JavaScript里有两种字符串相关的类型:
- 原始字符串类型:像
b='adddd'这种字面量创建的,属于JavaScript的7种原始类型之一(其余是number、boolean、null、undefined、symbol、bigint)。typeof对原始字符串的判断就是'string'。 - String包装对象:
new String("aaaa")是通过构造函数手动创建的对象,它本质是一个对象,只是内部封装了字符串值。所以typeof检测它时会返回'object'。
这里要提一下:平时我们调用原始字符串的方法(比如'hello'.toUpperCase())时,JavaScript会自动把原始字符串临时包装成String对象,调用完方法后就销毁这个临时对象——这就是为什么原始字符串能调用对象方法,但本身不是对象的原因。
2. 为什么Object.prototype.toString.call()的结果相同?
Object.prototype.toString.call()是JavaScript中最可靠的类型判断方式之一,它的核心逻辑是读取目标值的内部类型标记(早期是[[Class]]属性,现在对应Symbol.toStringTag)。
- 对于原始字符串
b:当你用Object.prototype.toString.call(b)时,JavaScript会自动把这个原始值临时包装成对应的String对象,然后读取它的内部类型标记,所以返回[object String]。 - 对于手动创建的String对象
a:它本身就是String类型的实例,内部的类型标记就是String,所以调用这个方法时直接返回[object String]。
额外小提示
日常开发中几乎不需要手动创建new String()这种包装对象,因为原始字符串已经能满足绝大多数需求。只有在极少数场景下(比如需要给字符串绑定自定义属性时),包装对象才有用——毕竟原始类型不能添加自定义属性,而包装对象可以。
内容的提问来源于stack exchange,提问作者tts
相关产品推荐
相关产品推荐

