【问题标题】:Print getters when and object is printed in typescript在打字稿中打印对象时打印吸气剂
【发布时间】:2021-12-15 12:51:36
【问题描述】:

TypeScript/JavaScript 中是否有一个选项可以使用 getter 打印具有私有属性的对象,而不是打印私有属性名称。

例如,我在 TypeScript 中有这个类

class Vehicle {

  constructor(private _brand: string, private _year: number) {}

  get brand(): string {
    return this._brand;
  }

  get year(): number {
    return this._year;
  }

  set year(year: number) {
    this._year = year;
  }

  set brand(brand: string) {
    this._brand = brand;
  }
}

const vehicle: Vehicle = new Vehicle('Toyota', 10);

console.log(vehicle);

我知道了

[LOG]: Vehicle: {
  "_brand": "Toyota",
  "_year": 10
} 

但我想知道我是否可以得到这样的东西

[LOG]: Vehicle: {
  "brand": "Toyota",
  "year": 10
} 

【问题讨论】:

  • TypeScript 中的 private 和 JavaScript 中的 Private class features 之间存在差异。 console.log(vehicle); 在 JavaScript 中进行评估,并且属性是公开的。
  • TypeScript 中的私有类属性在 JavaScript 中是公共的:typescriptlang.org/play?#code/…

标签: javascript typescript oop


【解决方案1】:

console.log 的作用因环境而异。如果你想做你所描述的,你必须编写自己的记录器函数,例如(在 JavaScript 中,但类型很容易添加)见 cmets:

function log(obj) {
    // Get the names of getter properties defined on the prototype
    const ctor = obj.constructor;
    const proto = ctor?.prototype;
    const names = new Set(
        proto
            ? Object.entries(Object.getOwnPropertyDescriptors(proto))
                .filter(([_, {get}]) => !!get)
                .map(([name]) => name)
            : []
    );
    // Add in the names of "own" properties that don't start with "_"
    for (const name of Object.keys(obj)) {
        if (!name.startsWith("_")) {
            names.add(name);
        }
    }
    // Create a simple object with the values of those properties
    const simple = {};
    for (const name of names) {
        simple[name] = obj[name];
    }
    // See if we can get a "constructor" name for it, apply it if so
    let objName =
        obj[Symbol.toStringTag]
        || ctor?.name;
    if (objName) {
        simple[Symbol.toStringTag] = objName;
    }
    // Log it
    console.log(simple);
}

现场示例:

"use strict";

function log(obj) {
    // Get the names of getter properties defined on the prototype
    const ctor = obj.constructor;
    const proto = ctor?.prototype;
    const names = new Set(
        proto
            ? Object.entries(Object.getOwnPropertyDescriptors(proto))
                .filter(([_, {get}]) => !!get)
                .map(([name]) => name)
            : []
    );
    // Add in the names of "own" properties that don't start with "_"
    for (const name of Object.keys(obj)) {
        if (!name.startsWith("_")) {
            names.add(name);
        }
    }
    // Create a simple object with the values of those properties
    const simple = {};
    for (const name of names) {
        simple[name] = obj[name];
    }
    // See if we can get a "constructor" name for it, apply it if so
    let objName =
        obj[Symbol.toStringTag]
        || ctor?.name;
    if (objName) {
        simple[Symbol.toStringTag] = objName;
    }
    // Log it
    console.log(simple);
}

class Vehicle {
    constructor(_brand, _year) {
        this._brand = _brand;
        this._year = _year;
    }
    get brand() {
        return this._brand;
    }
    get year() {
        return this._year;
    }
    set year(year) {
        this._year = year;
    }
    set brand(brand) {
        this._brand = brand;
    }
}
const vehicle = new Vehicle('Toyota', 10);
log(vehicle);

有很多空间可以根据您的喜好进行调整,这只是您如何进行的草图。

【讨论】:

  • 感谢您的回答。我想知道是否有本地方法可以做到这一点。如果我们正在使用 OOP 私有属性名称,即使从控制台日志中也不应该公开,对吧?
  • @VíctorCardozo - 这完全取决于控制台日志记录功能的实现,但通常我希望它们会显示出来,因为console.log 是一个调试工具。记住 TypeScript 的“私有”属性仅从编译时的角度来看是私有的也很有用。在运行时,它们是普通的公共属性。但即使是真正的私有字段(JavaScript 现在有这些)也会由 Chrome 的 devtools 控制台(而不是 Node.js 的)显示。
【解决方案2】:

我不认为有办法做到这一点,但你可以在类中创建一个日志方法,如下所示:

  log() {
    console.log({
      brand: this.brand,
      year: this.year,
    });
  }

然后只需拨打vehicle.log();

然后你会得到这样的日志{brand: 'Toyota', year: 10}

【讨论】:

    猜你喜欢
    • 2021-07-19
    • 1970-01-01
    • 2017-01-26
    • 2017-04-23
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多