HOWTO · JavaScript
如何检查 JavaScript 中的变量是否为字符串
本教程介绍了如何在 JavaScript 中检查变量是否为字符串。
本页内容
使用 typeof value === "string" 检查某个值是否为原始字符串。这通常是验证字符串时的首选方式。单引号、双引号和反引号都能创建原始字符串;引号形式不会改变值的类型。
使用 typeof 检查原始字符串
对于原始字符串,typeof 操作符会返回字符串 "string"。将结果与这个确切的值进行比较。对于数字、布尔值、null 和对象,比较结果为 false。此方法适用于本地值、函数参数以及从其他代码接收的值。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
const primitive = "hello";
const boxed = new String("hello");
const number = 42;
console.log(typeof primitive);
console.log(typeof boxed);
console.log(typeof number === "string");
string
object
false
原始字符串的结果是 "string";通过 new String("hello") 创建的值结果是 "object";而 42 不符合原始字符串的条件。验证值时,请使用 typeof value === "string" 进行比较。
决定是否接受 String 对象
JavaScript 还提供 String 对象,有时也称为包装字符串。new String("hello") 会创建一个 String 对象,而不带 new 的 String("hello") 会返回原始字符串。通常优先使用原始字符串:包装后的值具有对象行为,可能会导致比较和 API 调用出现意外结果。
typeof 检查会接受原始字符串并拒绝 String 对象,因为 typeof new String("hello") 的结果是 "object"。对于输入验证,这通常是正确的行为。如果某个 API 有意接受这两种形式,应明确作出这个决定,而不是放宽所有字符串检查。
value instanceof String 检查当前 realm 中的 String.prototype 是否出现在该值的原型链中。对于原始字符串,它会返回 false;对于在其他 realm 中创建的真正 String 对象(例如另一个浏览器窗口或框架中的对象),它也可能返回 false。它不能证明某个对象具有 String 包装对象的内部数据。
了解其他检查方式的局限
Object.prototype.toString.call(value) === "[object String]" 可以识别原始字符串和普通 String 对象,包括许多跨 realm 对象。但它不能普遍验证对象的真实性:对象可以通过 Symbol.toStringTag 自定义返回结果。只有当这一局限适用于代码处理的值时,才使用这种检查。
String.prototype.isPrototypeOf(value) 检查当前 realm 的 String.prototype 是否出现在某个对象的原型链中。它适用于对象,不适用于原始值,并且与 instanceof 一样存在跨 realm 的局限。此方法和 instanceof String 都不能证明该值是真正的 String 包装对象或包含内部字符串数据;例如,Object.create(String.prototype) 可以通过这两种原型链检查。这些检查回答的问题各不相同,不能互换使用。对于常规类型验证,请使用 typeof value === "string",并单独决定是否将包装对象纳入可接受的输入。
常见问题
如何在 JavaScript 中检查变量是否为字符串?
使用 typeof value === "string" 接受原始字符串。这是大多数应用程序输入的标准做法。如果还要接受包装值,应单独明确这项策略;仅检查原型链并不能证明某个对象是真正的 String 包装对象。
原始字符串和 String 对象有什么区别?
原始字符串是一个字符串值。new String("hello") 会创建一个包装该值的对象,因此 typeof 返回 "object"。除非某个 API 特别需要 String 对象,否则应优先使用原始字符串。
instanceof String 能检查原始字符串吗?
不能。instanceof 会检查某个对象是否继承自当前 realm 的 String 构造函数。原始字符串不是对象。
应该选择哪种检查方式?
验证原始字符串时使用 typeof。只有在需要检查同一 realm 中的 String 原型链时,才使用 instanceof String 或 String.prototype.isPrototypeOf();两者都不能证明值是真正的包装对象。若需要识别原始字符串和包装字符串,可以使用 Object.prototype.toString.call(),但要考虑 Symbol.toStringTag 对结果的自定义。真正的跨 realm 包装对象可能无法通过同一 realm 的原型链检查。