TypeScript中String()与new String()的区别及使用注意事项
TypeScript中
String()与new String()的差异和使用问题 核心本质区别
二者的返回值从根上就不是一类东西:
String()是普通的类型转换函数,调用后直接返回原始类型string,不存在对象包装过程。你提到的String('hello') === 'hello'返回true,本质就是因为两边都是原始字符串,值完全一致,属于严格相等。new String()是构造函数调用,执行后会创建一个String类的实例对象,返回值是引用类型Object,本质是堆内存里存的一个包装对象,不是原始值。
混用/不当选择会遇到的问题
不要觉得二者表现差不多就随便用,踩坑的场景非常多:
- 全等判断意外失效
你以为内容一样就相等,但只要混了new出来的包装对象,全等判断直接不成立:const str1 = String('hello') const str2 = new String('hello') console.log(str1 === str2) // false!原始值和对象不可能严格相等 console.log(typeof str1) // 输出"string" console.log(typeof str2) // 输出"object" // 哪怕是两个new出来的同内容字符串,也永远不会相等 const str3 = new String('hello') console.log(str2 === str3) // false,引用类型比较的是内存地址,两个独立实例地址不同 - 类型校验逻辑错乱
常规判断字符串的逻辑对new String()生成的值完全无效,很容易触发业务bug:
在TypeScript环境下二者的类型定义本身就不兼容:const strObj = new String('test') console.log(typeof strObj === 'string') // false,和预期判断结果完全相反String()的返回值类型是原始类型string,new String()的返回值类型是对象类型String。如果把new String()生成的实例传给要求参数为string的函数、接口,TS会直接报类型不匹配的错误。 - 破坏字符串不可变特性
原始字符串是不可变值,你没法给它挂载自定义属性;但new String()返回的是普通对象,可以随意修改、添加属性,很容易埋下隐蔽的逻辑问题:const normalStr = String('hello') normalStr.tag = 'test' // 严格模式下直接报错,非严格模式赋值后访问也会返回undefined const objStr = new String('hello') objStr.tag = 'test' console.log(objStr.tag) // 正常输出"test",属性被持久挂载到了对象上 - 无意义的性能开销
原始字符串是栈内存存储的简单值,访问、传递的成本极低;new String()生成的包装对象需要在堆内存开辟空间,还要维护原型链、属性存储结构,无理由使用只会带来额外的性能损耗。
使用建议
日常开发里几乎所有场景都应该用String()做字符串转换,或者直接使用字符串字面量,完全不需要用new String()。除非你明确需要一个可扩展属性的字符串包装对象——但这种需求在实际业务中几乎不会出现。
内容的提问来源于stack exchange,提问作者Žilvinas Rudžionis
相关产品推荐
相关产品推荐

