JavaScript 的类型系统

JavaScript 的类型系统

这篇博客文章将探讨 JavaScript 的类型系统。用来回答这些问题:JavaScript 是动态类型?弱类型?什么是强制类型转换?

JavaScript 的类型

JavaScript 实现了 ECMAScript 语言规范的仅有 7 种类型[1]

ECMAScript 语言类型与 ECMAScript 编程人员直接操作的 ECMAScript 语言值对应。ECMAScript 语言类型有:

  • Undefined
  • Null
  • Boolean
  • String
  • Number
  • Object
  • Symbol

Symbol 类型是 ES6 新加入的基础类型(primitive type),每个 Symbol 值都是唯一且不可变的。Symbol 值可以作为对象(Object)属性。

const sym = Symbol();
const bar = {
  [sym]: true,
};
console.log(bar[sym]); // true

静态与动态

在语义和类型系统的上下文中,“静态”通常是指“编译时” 或者 “不是程序运行时”,而"动态"意味着“运行时”。

静态类型与动态类型

在静态类型语言中,编译器在编译阶段知晓变量、参数和对象成员的类型。编译器可以使用这些信息来做类型检查和优化编译的代码。

甚至在静态类型语言中,一个变量(以及其它)也能有动态类型,变量的值类型在运行时获取。动态类型能区别与静态类型。Java 的例子:

Object foo = "abc";

foo 的静态类型是 Object,它的动态类型是 String

JavaScript 是动态类型语言,变量的类型在编译阶段通常不知晓。

静态类型检查与动态类型检查

如果你有类型信息,那么你可以查看值的正确类型,即使它是其它地方(函数返回,任务产生等)转换获取的。静态类型语言在编译阶段检查类型,动态类型语言在运行时检查。一种语言可以同时有静态类型检查和动态类型检查。如果检查失败,你通常会得到一些类型错误或异常。

JavaScript 提供非常有限的动态类型检查,

const foo = null;
foo.prop; // TypeError: Cannot read property 'prop' of null

通常地,然而,事情经常静默地失败或者运行。举例来说,如果你获取不存在的属性,你将得到值 undefined

const bar = {};
bar.prop; // undefined

强制类型转换

在 JavaScript 中,处理不匹配的值的主要方式是强制转换为正确的类型。强制意味着隐式类型转换。大多数的操作是强制的:

'3' * '4'; // 12

JavaScript 有自己内部函数来显式类型转换。其中一些可以通过语言中的函数 BooleanNumberStringObject 来实现。

Number(true); // 1
Number('123'); // 123
String(true); // 'true'

JavaScript 内置的转换机制仅于类型 Boolean、Number、String 和 Object 有效。没有转换一个构造方法实例到另一个构造方法实例的标准方法。

不要使用强类型和弱类型

术语“强类型”和“弱类型”没有有用的定义。人们一直使用它们,但是更好的是使用其它的比如静态类型和静态类型检查等等。

引用

  1. ECMAScript: language-types
  2. JavaScript 中值分类

本文作者 Axel Rauschmayer,转载请注明来源链接:

原文链接:https://2ality.com/2013/09/types.html

本文链接:https://tie.pub/2019/06/types-in-javascript/