用几个小时来制定计划,可以节省几周的编程时间。
首先说明,强弱类型之分不是某一个权威机构定义的,而是在 1974 年由两位计算机科学家提出:
在强类型语言中,当一个对象从调用函数传递到被调用函数时,其类型必须与被调用函数中声明的类型兼容。—— Liskov, Zilles 1974
所以现在强类型和弱类型还有较大争议,普遍认为强类型有更强的类型约束,而弱类型中几乎没有约束。
类型系统
强类型
- 语言层面限制函数的实参类型必须与形参类型相同
- 强类型语言中不允许任意的隐式类型转换
优势
- 错误更早暴露
- 代码提示更智能
- 编码更准确重构更牢靠
- 减少不必要的类型判断
弱类型
- 弱类型语言层面不会限制实参的类型
- 弱类型语言允许任意的数据隐式类型转换
静态类型
一个变量声明时它的类型就是明确的,声明过后它的类型不再允许修改
动态类型
运行阶段才能够明确变量类型,变量的类型随时可以改变
动态类型语言中的变量没有类型(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));