typeof 的定义
typeof操作符返回一个字符串,表示未经计算的操作数的类型。
console.log(typeof 12); // "number"
console.log(typeof 'webxiu'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof name); // 操作一个未定义的变量 "undefined"
返回值的解释
从上面的例子我们可以看出,typeof 操作符用于检测给定变量的数据类型。对于一个值使用 typeof 操作符,可能返回以下几个字符串:
- boolean – 代表这个值是布尔值
- string – 代表这个值是字符串
- number – 代表这个值是数值
- symbol – 代表这个值是Symbol
- undefined – 代表这个值未定义
- object – 代表这个值是对象或null
- function – 代表这个值是函数
返回 boolean、string、number 的情况
对于布尔值、字符串、数字使用typeof 操作符,分别返回 “boolean”、“string”、“number”
//Numbers
typeof 12 === 'number'
typeof 3.14=== 'number'
typeof Math.LN2 === 'number'
typeof Infinity === 'number'
typeof NaN === 'number'
typeof Number(1) === 'number'
// Strings
typeof '' === 'string'
typeof 'webxiu' === 'string'
typeof (typeof 1) === 'string'
typeof String('webxiu') === 'string'
// Booleans
typeof true === 'boolean'
typeof false === 'boolean'
typeof Boolean(true) === 'boolean'
返回 symbol 的情况
对 Symbol 类型的值使用 typeof 操作符时,会返回 “symbol” Symbol 是 ECMAScript 6 新增的类型
//Symbols
typeof Symbol() === 'symbol'
typeof Symbol('webxiu') === 'symbol'
typeof Symbol.iterator === 'symbol'
返回 undefined 的情况
//Undefined
typeof undefined === 'undefined'
typeof name === 'undefined'
typeof undeclaredVariable === 'undefined'
对 undefined 使用 typeof 操作符,返回 “undefined” 未赋值的变量,默认值为 undefined ,对未赋值的变量使用 typeof 操作符,返回 “undefined”
需要注意的问题
在 ECMAScript 6 之前,typeof总是保证为任何操作数返回一个字符串,所以当对未定义的变量使用 typeof 操作符时,也会返回 “undefined”, 所以在 ECMAScript 6 之前,typeof 操作符时一个完全安全的操作,永远不会抛出错误。
但在 ECMAScript 6 中,引入了暂时性死区的概念,在变量声明之前,对块中的 let 和 const 变量使用 typeof 操作符时,会抛出一个 ReferenceError
看一个例子
let a = 1
// a 已经声明并且是数字
typeof a === 'number'
// b 是未定义变量,并且当前块作用域中,没有与之同名的通过let和const声明的变量
typeof b === 'undefined'
// 当前块作用域中,通过let声明了c,在c未初始化之前,存在暂时性死区,此时使用typeof 抛出ReferenceError
typeof c // ReferenceError
let c
typeof undefined === 'undefined'
typeof name === 'undefined'
typeof undeclaredVariable === 'undefined'
返回 function 的情况
当对函数使用 typeof 操作符的时候,会返回 “function”
typeof function(){} === 'function'
typeof class C{} === 'function'
typeof Math.sin === 'function'
typeof new Function() === 'function'
需要注意的问题
这里有一个历史遗留问题,需要我们考虑
当我们的浏览器环境是 Safari 5 及以前版本、Chrome 7 及以前版本 在对正则表达式对象使用 typeof 操作符时,也会返回 “function”, 实际在 ECMAScript 的规范中,应该返回 “object”
返回 object 的情况
对于不是函数的引用类型的值,使用 typeof 操作符时,会返回 “object”
typeof {a: 1} === 'object'
typeof [1,2,3] === 'object'
typeof new Date() === 'object'
typeof new Boolean(true) === 'object'
typeof new Number(1) === 'object'
typeof new String('webxiu') === 'object'
对于 null 使用 typeof 操作符时,也会返回 “object”
typeof null === 'object' // 从一开始出现js就是这样的
这是由于在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"
例外情况
上面的所有内容,其实基本概括了所有使用 typeof 操作符的情况 但是在这其中有一个例外情况:
当前所有的浏览器都暴露了一个非标准的宿主对象 document.all
我们在对 document.all 使用 typeof 操作符时,会返回 “undefined”
typeof document.all === 'undefined'