一、类型
大多数开发者认为,像 JavaScript 这样的动态语言是没有类型(type)的。
我们这样来定义“类型”:对语言引擎和开发人员来说,类型是值的内部特征,它定义了值的行为,以使其区别于其他值。
二、内置类型
JavaScript 有七中内置类型:
- 空值(null)
- 未定义(undefined)
- 布尔值(boolean)
- 数字(number)
- 字符串(string)
- 对象(object)
- 符号(symbol,ES6 中新增)
Tips:除对象外,其他统称为“基本类型”。
我们可以使用 typeof
运算符来查看值的类型,它返回的是类型的字符串值。
typeof undefined === 'undefined' // true
typeof null === 'object' // true
typeof true === 'boolean' // true
typeof 42 === 'number' // true
typeof 'abc' === 'string' // true
typeof {} === 'object' // true
typeof Symbol() === 'symbol' // true
我们可以注意到 null 类型不在此列。它比较特殊,需要使用复合条件来检测 null 值的类型:
let a = null
(!a && typeof a === 'object') // true
还有一种情况:
typeof function() {} === 'function' // true
三、值和类型
JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。
换个角度来理解就是,JavaScript 不做“类型强制”;也就是说,语言引擎不要求变量总是持有与其初始值同类型的值。一个变量可以现在被赋值为字符串类型值,随后又被赋值为数字类型值。
3.1 undefined 和 undeclared
变量在未赋值的时候为 undefined
。此时 typeof
返回 undefined
:
let a
typeof a // 'undefined'
大多数开发者倾向于将 undefined
等同于 undeclared(未声明)
,但在 JavaScript 中它们完全是两回事。
已在作用域中声明但还没有赋值的变量,是 undefined
的。相反,还没有在作用域中声明过的变量,是 undeclared
的。
例如:
let a
a // undefined
b // ReferenceError: b is not defined
浏览器对这类情况的处理稍微有点不妥。上例中,“b is not defined”容易让人误以为是“b is undefined”。这里再强调一遍,undefined
和 undeclared
是两码事。
还需要注意的是 typeof
处理 undeclared
变量的方式。例如:
let a
typeof a // 'undefined'
typeof b // 'undefined'
对于 undeclared
变量,typeof
照样返回 undefined
。虽然 b 是一个 undeclared
变量,但 typeof b
并没有报错。这是因为 typeof
有一个特殊的安全防范机制。
3.2 typeof Undeclared
该安全防范机制对在浏览器中运行的 JavaScript 代码来说还是很有帮助的,因为多个脚本文件会在共享的全局命名空间中加载变量。
如何在程序中检查全局变量,确保不会出现 ReferenceError 错误。这时 typeof
的安全防范机制就成了我们的好帮手:
// 这样会抛出错误
if (GlobalVariable) {
/* */
}
// 这样是安全的
if (typeof GlobalVariable !== 'undefined') {
/* */
}
四、小结
- JavaScript 中有七种内置类型:null、undefined、boolean、string、number、object 和 symbol ,可以使用
typeof
运算符来查看。 - 变量没有类型,但它们持有的值有类型。类型定义了值的行为特征。
- 很多开发人员讲
undefined
和undeclared
混为一谈,但在 JavaScript 中它们是两码事。undefined
是值的一种。undeclared
则表示变量还没有被声明过。 - 遗憾的是,JavaScript 却将它们混为一谈,在我们试图访问
undeclared
变量时这样报错:ReferenceError: a is not defined,并且typeof
对undefined
和undeclared
变量都返回undefined
。 - 然而,通过
typeof
的安全防范机制(阻止报错)来检查undeclared
变量,有时是个不错的办法。
参考资料
- 《你不知道的Javascript(中卷)》