typeof

typeof 运算符返回一个字符串,指示操作数的值的类型。

试一试

语法

js
typeof operand

参数

操作数

表示要返回其类型的对象或原始值的表达式。

描述

下表总结了 typeof 的可能返回值。有关类型和原始值的更多信息,还可以查看JavaScript 数据结构页面。

类型 结果
未定义 "undefined"
"object" (原因)
Boolean "布尔"
Number "数字"
BigInt "bigint"
String "字符串"
Symbol "符号"
函数(在 ECMA-262 术语中实现 [[Call]];也是函数) "function"
任何其他对象 "object"

此值列表是详尽的。据报道,没有符合规范的引擎会生成(或历史上曾生成)除了列出的值之外的其他值。

示例

基本用法

js
// Numbers
typeof 37 === "number";
typeof 3.14 === "number";
typeof 42 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // Despite being "Not-A-Number"
typeof Number("1") === "number"; // Number tries to parse things into numbers
typeof Number("shoe") === "number"; // including values that cannot be type coerced to a number

typeof 42n === "bigint";

// Strings
typeof "" === "string";
typeof "bla" === "string";
typeof `template literal` === "string";
typeof "1" === "string"; // note that a number within a string is still typeof string
typeof typeof 1 === "string"; // typeof always returns a string
typeof String(1) === "string"; // String converts anything into a string, safer than toString

// Booleans
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(1) === "boolean"; // Boolean() will convert values based on if they're truthy or falsy
typeof !!1 === "boolean"; // two calls of the ! (logical NOT) operator are equivalent to Boolean()

// Symbols
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";

// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";

// Objects
typeof { a: 1 } === "object";

// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === "object";

typeof new Date() === "object";
typeof /regex/ === "object";

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";

// Functions
typeof function () {} === "function";
typeof class C {} === "function";
typeof Math.sin === "function";

typeof null

js
// This stands since the beginning of JavaScript
typeof null === "object";

在 JavaScript 的第一个实现中,JavaScript 值表示为类型标记和值。对象的类型标记为 0null 表示为 NULL 指针(在大多数平台上为 0x00)。因此,null 的类型标记为 0,因此 typeof 的返回值为 "object"。(参考

为 ECMAScript 提出了一个修复程序(通过选择加入),但被拒绝了。它将导致 typeof null === "null"

使用 new 运算符

所有使用new调用的构造函数都将返回非原始值("object""function")。大多数返回对象,但值得注意的例外是Function,它返回一个函数。

js
const str = new String("String");
const num = new Number(100);

typeof str; // "object"
typeof num; // "object"

const func = new Function();

typeof func; // "function"

语法中需要括号

typeof 运算符的优先级高于加法(+)等二元运算符。因此,需要括号来计算加法结果的类型。

js
// Parentheses can be used for determining the data type of expressions.
const someData = 99;

typeof someData + " Wisen"; // "number Wisen"
typeof (someData + " Wisen"); // "string"

与未声明和未初始化变量的交互

typeof 通常始终保证为其提供的任何操作数返回一个字符串。即使对于未声明的标识符,typeof 也会返回 "undefined" 而不是抛出错误。

js
typeof undeclaredVariable; // "undefined"

但是,在声明位置之前,对同一块中的词法声明(let constclass)使用 typeof 将抛出ReferenceError。块作用域变量处于从块开始到初始化处理完成之前的暂时性死区中,在此期间,如果访问它,它将抛出错误。

js
typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError

let newLetVariable;
const newConstVariable = "hello";
class newClass {}

document.all 的异常行为

所有当前浏览器都公开了一个非标准的主机对象document.all,其类型为 undefined

js
typeof document.all === "undefined";

尽管 document.all 也是假值并且宽松地等于undefined,但它不是undefineddocument.all 类型为 "undefined" 的情况在 Web 标准中被归类为出于 Web 兼容性目的而“故意违反”原始 ECMAScript 标准。

获取更具体类型的自定义方法

typeof 非常有用,但它可能不如所需的那样通用。例如,typeof []"object"typeof new Date()typeof /abc/ 等也是如此。

为了更具体地检查类型,这里我们提供了一个自定义 type(value) 函数,它主要模仿 typeof 的行为,但对于非原始值(即对象和函数),它会在可能的情况下返回更细粒度的类型名称。

js
function type(value) {
  if (value === null) {
    return "null";
  }
  const baseType = typeof value;
  // Primitive types
  if (!["object", "function"].includes(baseType)) {
    return baseType;
  }

  // Symbol.toStringTag often specifies the "display name" of the
  // object's class. It's used in Object.prototype.toString().
  const tag = value[Symbol.toStringTag];
  if (typeof tag === "string") {
    return tag;
  }

  // If it's a function whose source code starts with the "class" keyword
  if (
    baseType === "function" &&
    Function.prototype.toString.call(value).startsWith("class")
  ) {
    return "class";
  }

  // The name of the constructor; for example `Array`, `GeneratorFunction`,
  // `Number`, `String`, `Boolean` or `MyCustomClass`
  const className = value.constructor.name;
  if (typeof className === "string" && className !== "") {
    return className;
  }

  // At this point there's no robust way to get the type of value,
  // so we use the base implementation.
  return baseType;
}

为了检查可能不存在的变量,否则这些变量会抛出ReferenceError,请使用 typeof nonExistentVar === "undefined",因为此行为无法用自定义代码模拟。

规范

规范
ECMAScript 语言规范
# sec-typeof-operator

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅