如何将类的所有属性传递给父构造函数类?

时间:2018-08-19 11:15:32

标签: typescript oop typescript2.0

我有以下课程:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one below. Where do they line-breaks go in FF?</div>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one above. Where do they line-breaks go FF?</div>

我需要将类export class FilterClassJournalConclusions extends FilterAbstract implements IFilterClassJournalConclusions { public class: number; public suffix: string; public number: number; public year: number; public subject: number; public constructor() { super(); this.model = this.class; } } 的所有属性作为对象传递给父构造函数:

FilterClassJournalConclusions

但是它看起来很丑陋和多余,如何美化它?

1 个答案:

答案 0 :(得分:2)

您无法在this执行完毕之前访问super。这是因为允许您 访问构造函数中父级的属性。检查后,我什至无法在示例类中调用super({ a: this.a })。这是有道理的,因为this.a可以在类中初始化为a = this.b + 2,其中b是父属性!

虽然一切都没有丢失!如果您希望父类访问子级,则可以这样做。请注意,super在子代构造函数之前完成...因此,在父代构造函数中访问子代通常会产生不幸的后果。

想象一下,您的FilterClassJournalConclusions是为数不多的子类之一,这些子类定义了一些我们想用来从超大列表中筛选出子集的值/条件,以及父类FilterAbstract处理花式过滤逻辑;它只需要知道如何进行过滤。

以下示例中的泛型允许父类返回从子类的形状派生的值(如果您选择让父级访问子级的途径,通常会希望这样做)。

以下是如何完成此操作的示例:

interface IFilterClassJournalConclusions {
  filterAttributes: { [key: string]: number | string };
}

class FilterAbstract<T extends IFilterClassJournalConclusions> {
  constructor() {};
  private get child(): T {
    return this as any; // cast this to the type of the child
  }
  biggestList(): any[] {
    return [{}, { class: 2 }, { year: 1999 }, { suffix: 'Jr.' }]
  }
  private matches(element: any): element is Partial<T['filterAttributes']> {
    return Object.keys(element).some(key => element[key] === this.child.filterAttributes[key])
  }
  filter(): Partial<T['filterAttributes']>[] {
    const results: Partial<T['filterAttributes']>[] = [];
    this.biggestList().forEach(element => {
      if (this.matches(element)) { 
        results.push(element); 
      }
    })
    return results;
  }
}

class FilterClassJournalConclusions extends FilterAbstract<FilterClassJournalConclusions> implements IFilterClassJournalConclusions {
  filterAttributes = {
    class: 'best highschool',
    year: 1999
  }
}

// note the type is Partial<{ class: string; year: number }>[]
const filtered = new FilterClassJournalConclusions().filter();

console.log(filtered); // [{ year: 1999 }]

在我看来,这种策略随着时间的流逝是痛苦的,并且比在继承中应用合成更不受欢迎。看起来更像这样:

interface IFilterClassJournalConclusions {
  filterAttributes: { [key: string]: number | string };
}

class Filterer{
  constructor() {};
  biggestList(): any[] {
    return [{}, { class: 2 }, { year: 1999 }, { suffix: 'Jr.' }]
  }
  private matches<T extends IFilterClassJournalConclusions>(definition: T, element: any): element is Partial<T['filterAttributes']> {
    return Object.keys(element).some(key => element[key] === definition.filterAttributes[key])
  }
  filter<T extends IFilterClassJournalConclusions>(filterWith: T): Partial<T['filterAttributes']>[] {
    const results: Partial<T['filterAttributes']>[] = [];
    this.biggestList().forEach(element => {
      if (this.matches(filterWith, element)) { 
        results.push(element); 
      }
    })
    return results;
  }
}

class FilterClassJournalConclusions implements IFilterClassJournalConclusions {
  filterAttributes = {
    class: 'best highschool',
    year: 1999
  }
}

// note the type is Partial<{ class: string; year: number }>[]
const filtered = new Filterer().filter(new FilterClassJournalConclusions());

console.log(filtered); // [{ year: 1999 }]