typeof
typeof
运算符返回一个字符串,指示操作数值的类型。
¥The typeof
operator returns a string indicating the type of the operand's value.
Try it
语法
参数
描述
¥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.
示例
基本用法
¥Basic usage
// 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
// This stands since the beginning of JavaScript
typeof null === "object";
在 JavaScript 的第一个实现中,JavaScript 值表示为类型标记和值。对象的类型标记是 0
。null
表示为 NULL 指针(大多数平台中为 0x00
)。因此,null
将 0
作为类型标记,因此 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.
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.
// 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.
typeof undeclaredVariable; // "undefined"
但是,在声明位置之前的同一块中的词法声明(let
、const
和 class
)上使用 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.
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
.
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.
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 |
浏览器兼容性
BCD tables only load in the browser