好久不写了,今天推篇简单的。
众所周知,javascript 的继承方式也和 C、Java 有很大不同,javascript 使用原型继承,虽然在 ES6 中引入了关键字 class ,也只是语法糖而已。看如下代码:
我们定义了一个类 A,但是查看 A 的类型却不是 class ,也不是 object ,而是 function 。
当我们需要继承时,是基于原型链的。当我们访问 A.name 时,引擎首先会在 A 中找 name 属性,如果没有则顺着原型链一直找,当找到原型链顶端依然没有时,则返回 undefined 。
在 ES6 中不仅引入了 class ,也引入了 super ,用于在本类中访问父类。那么问题就来了,看下面代码:
"use strict";
class Point {
getX() {
console.log(this.x); // C
}
}
class ColorPoint extends Point {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(this.x) // A
console.log(super.x) // B
}
m() {
this.getX()
}
}
const cp = new ColorPoint();
cp.m();
在子类中,先把 this.x 赋值为 2 ,再把 super.x 赋值为 3 。
当我看到这段代码后的第一直觉是,应该输出 2 、 3 、 2 。我觉得子类的 x 是 2 ,父类的 x 是 3 。
当我把代码放到 Chrome(58.0.3029.110 (64-bit)) 中运行时,输出的结果居然是 3 、 undefined 、 3 。
考虑到有些老版本浏览器不支持 ES6 特性,于是我把代码放到 Babel Repl(6.24.2) 中执行,得到的结果是 2 、 undefined 、 2 。
随后我又把这段代码放到了 TypeScript 2.3 中,得到的结果是 2 、 3 、 2 ,居然和我的直觉是一致的。Anders Hejlsberg 不愧是 C# 之父,有人调侃 TypeScript:前端这么火,Hejlsberg 为了怕 C# 程序员失业后挨饿,因此发明了 TypeScript。
|
A |
B |
C |
Builtin |
3 |
undefined |
3 |
babel |
2 |
undefined |
2 |
TypeScript |
2 |
3 |
2 |
最后请教了贺师俊:
隐隐觉得 javascript 要变成 java 了。再次印证了那句话:一部分人害怕 javascript 会变成 java,而另一部分人正在努力把它变成 java。
|
请发表评论