【问题标题】:Naming convention for class properties in TypeScriptTypeScript 中类属性的命名约定
【发布时间】:2017-03-28 00:56:00
【问题描述】:

根据offical style guide你应该

避免在私有属性和方法前加上下划线。

由于我来自 Java 背景,我通常只会使用 this 关键字:

export default class Device {
    private id: string;

    constructor(id: string) {
        this.id = id;
    }

    public get id(): string { // [ts] Duplicate identifier 'id'.
        return this.id;
    }

    public set id(value: string) { // [ts] Duplicate identifier 'id'.
        this.id = value;
    }
}

但 TypeScript 编译器抱怨:[ts] Duplicate identifier 'id'.

TypeScript 构造函数中的参数命名是否有约定或最佳实践?

使用 TypeScript 的 getset 属性会产生错误。

有没有办法遵循样式指南并使用 TypeScript 的 get/set 属性?

【问题讨论】:

  • 不幸的是,以最佳实践为中心的问题并不适合 Stack Overflow,因为它们主要会产生基于意见的答案(“我喜欢这样做......”,“人们通常使用这个...... 。”)。虽然您可能会根据作者认为的“最佳实践”看到其他问题的答案,但专门询问它们是题外话。有关详细信息,请参阅help center。您可能希望从问题中删除偏离主题的部分,而只关注技术问题。
  • 不,the compiler doesn't complain。你的例子是有效的。
  • 对不起,我更新了我的问题,我错过了一些实际上导致错误的代码。
  • 你不能拥有它,因为它们最终都作为同一个 js 对象的属性。
  • 在您的情况下,您可以将 get id() / set id(val) 替换为简单的实例变量 id,声明为公共。更易于阅读和书写,性能更高。

标签: angular typescript parameters naming-conventions


【解决方案1】:

回答

如果你想使用getset 访问器,你必须在私有属性前加上下划线。在所有其他情况下不要使用它。我想说在访问器中使用下划线是一种特殊情况,虽然它没有明确写在Coding guidelines 中,但这并不意味着它是错误的。他们在official documentation 中使用它。

下划线的原因

首先,我想强调fieldproperty 之间的区别。在标准的高级 OOP 语言(如 Java 或 C#)中,字段是私有成员,其他类不应该看到。如果你想在封装的情况下公开它,你应该创建一个属性。

Java 中,您可以这样做(称为 Bean 属性):

private int id;

public int getId() {
    return this.id;
}

public setId(int value) {
    this.id = value;
}

然后您可以通过调用这些方法来访问该属性:

int i = device.getId();
device.setId(i);

//increment id by 1
device.setId(device.getId() + 1);

另一方面,C# 被设计成更容易使用属性:

private int id;

public int Id {
    get {
        return this.id;
    }
    set {
        this.id = value;
    }
}

(值始终是分配的值。)

您可以直接为这些属性赋值或获取属性值。

int i = device.Id;
device.Id = i;

//increment id by 1
device.Id++;

在纯 JavaScript 中,没有真正的字段,因为类成员始终是公共的;我们简单地称它们为属性。

TypeScript 中,您可以定义“真正的”类似 C# 的属性(带有封装)。为此,您使用Accessors

private _id: number;

public get id(): number {
    return this._id;
}

public set id(value: number) {
    this._id = value;
}

用法:

let i: number = device.id;
device.id = i;

//increment id by 1
device.id++;

必须在此处使用下划线,原因有两个:

  1. 在 JavaScript 中,所有类成员都是公共的。因此,通过在私有属性前加下划线,我们表示该属性(字段)是私有的,只能通过其公共属性访问。
  2. 如果您将私有属性和公共属性命名为相同的名称,JavaScript 解释器将不知道是访问私有属性还是公共属性。因此,您会收到您所写的错误:[ts] Duplicate identifier 'id'。

【讨论】:

    【解决方案2】:

    如果问题是严格的:

    有没有办法遵循 [typeScript] 样式指南并使用 get/set TypeScript 的属性?

    TypeScript 样式指南所说的:

    避免在私有属性和方法前加上下划线

    然后您可以使用$(美元符号)而不是_(下划线)来为您的私有字段添加前缀。通过这种方式,您既可以摆脱 [ts] Duplicate identifier 'blablabla' 错误,同时仍然遵守 TypeScript 样式指南。

    此外,这只是我的看法,.$combination 比 ._combination 更具可读性。

    【讨论】:

    • 这是错误的。美元前缀通常用于可观察对象。
    • “这些指南适用于 TypeScript 项目代码库的贡献者。这不是 TypeScript 社区的规定性指南。” github.com/Microsoft/TypeScript/wiki/Coding-guidelines
    • “美元前缀通常用于 observables”——这不是真的。对于 observables,通常使用美元 suffix。但我同意使用美元前缀而不是下划线前缀是没有意义的。两者都是邪恶的,但下划线的邪恶程度较小,因为它通常用于将财产标记为私有。这几乎是“标准”。
    • $ 用于 RxJS 中的 observables。不要这样做
    • _有什么不好的?
    【解决方案3】:

    对于属性访问器,您使用_

    查看来自 Microsoft https://www.typescriptlang.org/docs/handbook/classes.html#accessors 的示例:

    const fullNameMaxLength = 10;
    
    class Employee {
      private _fullName: string;
    
      get fullName(): string {
        return this._fullName;
      }
    
      set fullName(newName: string) {
        if (newName && newName.length > fullNameMaxLength) {
          throw new Error("fullName has a max length of " + fullNameMaxLength);
        }
    
        this._fullName = newName;
      }
    }
    
    let employee = new Employee();
    employee.fullName = "Bob Smith";
    if (employee.fullName) {
      console.log(employee.fullName);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      相关资源
      最近更新 更多