ES6 中的 this & super:babel 和 typescript 都错了
发布于 7 年前 作者 falost 6994 次浏览 来自 分享

众所周知,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

最后请教了贺师俊:

QQ图片20170524092353.png 隐隐觉得 javascript 要变成 java 了。再次印证了那句话:一部分人害怕 javascript 会变成 java,而另一部分人正在努力把它变成 java。

作者:justjavac 原文地址:https://mp.weixin.qq.com/s/X3wwv9svWx6dbhxEEFzbAA

回到顶部