类定义在Typescript和ES6中混淆

kua*_*ove 7 typescript ecmascript-6

所有:

我对ES6和打字稿很新,目前并排研究.

当我来到Class定义部分时,有一个问题:

在类声明中它们之间是否有一个主要的语法:

我发现的是:

在ES6中,只有声明方法但没有成员:

class Greeter {
    constructor(message) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
Run Code Online (Sandbox Code Playgroud)

在TypeScript中,它也允许声明成员变量:

class Greeter {
    // although it declare a variable "greeting" here, but I am not sure if it allows assignment initialization
    greeting: string; 
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是主要的语法差异(加上访问修饰符,还有一个关于修饰符的相关问题:我读过ES6类无法定义静态成员,那么允许定义静态方法有什么意义?)?

如果超过这个,还有什么需要注意的吗?

谢谢

Jer*_*one 5

我认为这里发生了两件事,第一,Typescript 的预期“类型擦除”含义:

打字稿

class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}
Run Code Online (Sandbox Code Playgroud)

将转换为 es6

class Greeter {
  constructor(message) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为 TypeScript 类型旨在被删除,并且假设“greeting: string”只是类型信息是公平的。

作为在类级别声明属性类型的自然扩展,TypeScript 允许初始化属性,这是 ES6 所没有的(需要在构造函数中定义/初始化这些属性)。

所以,这在打字稿中

class Greeter {
  greeting = "stranger";
  constructor(message: string) {
    this.greeting = message || this.greeting;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}
Run Code Online (Sandbox Code Playgroud)

这将被转译为 es6:

class Greeter {
  constructor(message) {
    this.greeting = "stranger";
    this.greeting = message || this.greeting;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}
Run Code Online (Sandbox Code Playgroud)

不知道为什么 es6 不允许在类定义中使用属性,但从 TypeScript 的角度来看,在类级别允许类型定义并在构造函数中进行初始化是非常奇怪的。

希望这能澄清事情。


Dan*_*ser 2

您确实可以向属性声明添加赋值,并且这些赋值基本上发生在您在构造函数主体中编写的其他操作之前。

class Greeter {
    greeting = "world!";

    constructor() {
    }

    greet() {
        return "Hello, " + this.greeting;
    }
}

console.log(new Greeter().greet()); // Prints "Hello, world!"
Run Code Online (Sandbox Code Playgroud)

另一方面是,如果您使用构造函数主体中范围内的任何内容,您将收到错误:

class Greeter {
    greeting = message; // Error: 'message' isn't defined here
    constructor(message: string) {
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
Run Code Online (Sandbox Code Playgroud)

TypeScript 也允许静态属性声明:

class Greeter {
    private static instancesCreated = 0;

    static getNumInstancesCreated() {
        return Greeter.instancesCreated;
    }

    constructor() {
        Greeter.instancesCreated++;
    }
}
Run Code Online (Sandbox Code Playgroud)

但这并不意味着静态方法本身没有用。ES6 没有实例属性声明,但实例方法仍然有用,因为您可以将属性附加到实例上。

有关更多信息,我鼓励您阅读TypeScript 手册上的 TypeScript 类以及TypeScript Deep Dive中的内容。