typeof

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

¥The typeof operator returns a string indicating the type of the operand's value.

Try it

语法

¥Syntax

js
typeof operand

参数

¥Parameters

operand

表示要返回类型的对象或 primitive 的表达式。

描述

¥Description

下表总结了 typeof 可能的返回值。有关类型和原语的更多信息,另请参阅 JavaScript 数据结构 页面。

¥The following table summarizes the possible return values of typeof. For more information about types and primitives, see also the JavaScript data structure page.

类型 结果
不明确的 "undefined"
无效的 "object"(reason)
布尔值 "boolean"
数字 "number"
BigInt "bigint"
字符串 "string"
符合 "symbol"
函数(实现 ECMA-262 术语中的 [[Call]];classes 也是函数) "function"
任何其他对象 "object"

这个值列表是详尽的。据报道,没有符合规范的发动机产生(或历史上产生过)所列值以外的值。

¥This list of values is exhaustive. No spec-compliant engines are reported to produce (or had historically produced) values other than those listed.

示例

¥Examples

基本用法

¥Basic usage

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)。因此,null0 作为类型标记,因此 typeof 返回值 "object"。(reference)

¥In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0. null was represented as the NULL pointer (0x00 in most platforms). Consequently, null had 0 as type tag, hence the typeof return value "object". (reference)

针对 ECMAScript 提出了修复(通过选择加入),但是 被拒绝。它会导致 typeof null === "null"

¥A fix was proposed for ECMAScript (via an opt-in), but was rejected. It would have resulted in typeof null === "null".

使用新运算符

¥Using new operator

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

¥All constructor functions called with new will return non-primitives ("object" or "function"). Most return objects, with the notable exception being Function, which returns a 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"

语法中需要括号

¥Need for parentheses in syntax

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

¥The typeof operator has higher precedence than binary operators like addition (+). Therefore, parentheses are needed to evaluate the type of an addition result.

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

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

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

¥Interaction with undeclared and uninitialized variables

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

¥typeof is generally always guaranteed to return a string for any operand it is supplied with. Even with undeclared identifiers, typeof will return "undefined" instead of throwing an error.

js
typeof undeclaredVariable; // "undefined"

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

¥However, using typeof on lexical declarations (let const, and class) in the same block before the place of declaration will throw a ReferenceError. Block scoped variables are in a temporal dead zone from the start of the block until the initialization is processed, during which it will throw an error if accessed.

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

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

document.all 的异常行为

¥Exceptional behavior of document.all

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

¥All current browsers expose a non-standard host object document.all with type undefined.

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

虽然 document.all 也是 falsy松散平等undefined,但它不是 undefined。具有类型 "undefined"document.all 的情况在 Web 标准中被分类为原始 ECMAScript 标准的 "故意违反",以实现 Web 兼容性。

¥Although document.all is also falsy and loosely equal to undefined, it is not undefined. The case of document.all having type "undefined" is classified in the web standards as a "willful violation" of the original ECMAScript standard for web compatibility.

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

¥Custom method that gets a more specific type

typeof 非常有用,但它的通用性没有可能需要的那么高。例如,typeof []"object",还有 typeof new Date()typeof /abc/ 等。

¥typeof is very useful, but it's not as versatile as might be required. For example, typeof [] is "object", as well as typeof new Date(), typeof /abc/, etc.

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

¥For greater specificity in checking types, here we present a custom type(value) function, which mostly mimics the behavior of typeof, but for non-primitives (i.e. objects and functions), it returns a more granular type name where possible.

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",因为无法使用自定义代码模仿此行为。

¥For checking potentially non-existent variables that would otherwise throw a ReferenceError, use typeof nonExistentVar === "undefined" because this behavior cannot be mimicked with custom code.

规范

Specification
ECMAScript Language Specification
# sec-typeof-operator

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看