众所周知,javascript 的继承方式也和 C、Java 有很大不同,javascript 使用原型继承,虽然在 ES6 中引入了关键字 class,也只是语法糖而已。看如下代码:
class A {};
typeof A ;
我们定义了一个类 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。
作者:justjavac 原文地址:https://mp.weixin.qq.com/s/X3wwv9svWx6dbhxEEFzbAA