JavaScript 是动态弱类型语言,TypeScript 呢?

2,459 阅读3分钟

用几个小时来制定计划,可以节省几周的编程时间。


首先说明,强弱类型之分不是某一个权威机构定义的,而是在 1974 年由两位计算机科学家提出:

在强类型语言中,当一个对象从调用函数传递到被调用函数时,其类型必须与被调用函数中声明的类型兼容。—— Liskov, Zilles 1974

所以现在强类型和弱类型还有较大争议,普遍认为强类型有更强的类型约束,而弱类型中几乎没有约束。

类型系统

b0aeb7ffd1667b9162e5329154d43777_720w.png

强类型

  • 语言层面限制函数的实参类型必须与形参类型相同
  • 强类型语言中不允许任意的隐式类型转换
💡 形参是函数声明时的变量,实参是调用该函数时传入的具体参数

优势

  • 错误更早暴露
  • 代码提示更智能
  • 编码更准确重构更牢靠
  • 减少不必要的类型判断

弱类型

  • 弱类型语言层面不会限制实参的类型
  • 弱类型语言允许任意的数据隐式类型转换

静态类型

一个变量声明时它的类型就是明确的,声明过后它的类型不再允许修改

动态类型

运行阶段才能够明确变量类型,变量的类型随时可以改变

动态类型语言中的变量没有类型(TS 的 ang),变量中存放的值是有类型的

总结

💡 TypeScript 是静态的、弱类型语言(有类型检查,类型不可更改,能够和 JS 一样进行隐式转换)
let num1: number = 1;
num1 = '1'; // error TS2322: Type 'string' is not assignable to type 'number'.

let str: string = 'str';
let num2: number = 2;
str = str + num2; // str2
💡 JavaScript 是动态的、弱类型语言(没有类型检查,类型可更改,可以隐式转换)
let cc = {};
cc = '1';

let aa = '123';
let bb = true;
aa = aa * bb; // 123

总的来说,谈论语言的“强”与“弱”并没有显得很有必要,它们在技术上没有标准的定义,最好是给出具体的问题进行具体的分析。如:”是否能保证调用方法时传入的实参类型与形参相同?“在 JavaScript 这是否定的,但在Java和TypeScript中是肯定的。

相比之下,静态类型和动态类型就没有争议了。静态类型是在编译时检查类型安全,并在编译时报错。而动态类型则是在代码运行期间检查值的类型,如在 JS 中访问 null、undefined 的属性;调用未声明的方法。

💡 TypeScript 在做算数运算时不能进行隐式转换
let aa: string = '123';
let bb: number = 1;
console.log(aa * bb); // The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
💡 Java 连接字符串进行隐式转换本质上是语法糖

(参见 Oracle 文档:第五章:类型转换

int x=20;
boolean y=true;
System.out.println("printing: " + x + y); // printing: 20true

// Java 编译器对代码进行重写
int x=20;
boolean y=true;
System.out.println("printing: " + new Integer(x).toString() + Boolean.toString(y));