如何访问Typescript方法中的构造函数参数

How to access a constructor parameter inside a Typescript method

本文关键字:方法 构造函数 参数 Typescript 何访问 访问      更新时间:2023-09-26

My Typescript class包含方法getProductAttributeByName(name: string),它过滤定义为构造函数参数的集合。

class Product {
    id: string;
    constructor(productDto: IProductDto) {
        this.id = productDto.id;
    }
    getProductAttributeByName(name: string): ProductAttribute {
        // I need productDto (the constructor parameter) here:
        return productDto.productAttributes.filter(x => x.name === name)
    }
}

这是不允许的,所以目前我在做:

class Product {
    id: string;
    productDto: IProductDto;
    constructor(productDto: IProductDto) {
        this.id = productDto.id;
        this.productDto = productDto;
    }
    getProductAttributeByName(name: string): ProductAttribute {
        return this.productDto.productAttributes.filter(x => x.name === name)
    }
}

不用说,这是可怕的。我公开了一个公共属性,它只需要在方法内部使用,唯一的原因是我不能访问构造函数参数。无奈之下,我还尝试将属性声明为private,如下所示:

class Product {
    id: string;
    private productDto: IProductDto;
    constructor(productDto: IProductDto) {
        this.id = productDto.id;
        this.productDto = productDto;
    }
    getProductAttributeByName(name: string): ProductAttribute {
        return this.productDto.productAttributes.filter(x => x.name === name)
    }
}

但这并不改变对象初始化后属性仍然可访问的事实:

var product = new Product(myDto);
// product.productDto is accessible!

是否有一种方法可以访问方法内部的构造函数参数,而不必声明可公开访问的属性?

"就因为我的方法不能访问构造函数参数…"考虑这个问题的方式是错误的。当实例化你的类时,productDto是你实例的一个重要状态吗?productDto中的数据是否包含Product在其生命周期中需要的重要信息?然后,您不仅试图在构造函数和某个方法之间传递它,而且该数据是对象状态的一部分。你的对象方法使用并依赖于那个状态。并且对象状态总是通过对象属性来实现的,所以将productDto保存在this.productDto上是完美的,也是正确的方法。

但是这并不能改变这样一个事实,即对象初始化后,该属性仍然是可访问的。

那又怎样?使用TypeScript和private声明,TypeScript将确保你不会因为试图从外部代码访问该属性而砸自己的脚。这就是你所需要的。实际上试图强制执行不可访问性是没有意义的。你只会竭尽全力,几乎得不到任何好处。许多Javascript对象都有内部状态,如果你愿意,你可以随意查看。这完全没问题。

这只是一个问题,如果你实际上是针对这些内部属性编写代码,而这些属性不应该是官方API的一部分,并且内部实现会改变。千万别这么做。同样,TypeScript的private可以帮助你实现这一点。

this.id = productDto.id;
this.productDto = productDto;

这是相当多余的。很明显,在其他方法中稍后需要productDto.id productDto。只需将整个productDto存储为属性,并根据需要访问其.id。如果你需要在你的类上公开id作为属性,使用返回this.prodctDto.idget方法可能是一个明智的主意:

class Product {
    private productDto: IProductDto;
    constructor(productDto: IProductDto) {
        this.productDto = productDto;
    }
    get id(): string {
        return this.productDto.id;
    }
    getProductAttributeByName(name: string): ProductAttribute {
        return this.productDto.productAttributes.filter(x => x.name === name)
    }
}

一般来说,尝试在设计类时不先编写构造函数。写出除构造函数以外的所有内容。设计您的类需要哪些内部和外部属性,以及您的方法将从哪些属性获取数据。然后,作为最后一步,编写构造函数,它需要确保对象状态是这样的,以便所有方法都能按设计工作。然后,"从构造函数传递到方法"的想法就会自动消除。