【问题标题】:TypeScript: custom class extending ArrayTypeScript:扩展数组的自定义类
【发布时间】:2018-10-23 13:28:10
【问题描述】:

我在使用扩展 Array 的自定义类时遇到了一些问题。我基本上只是想在 Array 类上添加一些辅助方法,这里我添加一个 logMe 方法,并为数组添加前缀。

class AAA extends Array {
  _prefix: string;

  constructor(prefix: string, values: number[]) {
    console.log('AAA contructor', values);

    // Use hack
    // https://stackoverflow.com/questions/35673043/extending-array-from-typescript
    super();
    this.push(...values);

    this._prefix = prefix;
  }

  logMe() {
    console.log('The prefix is:', this._prefix);
    console.log('The values are:');
    this.map(x => x * 2).forEach(console.log);
  }
}

这是我的测试:

const a = new AAA('PREFIX-A', [1, 2, 3]);
a.logMe();

预期结果:

AAA contructor [ 1, 2, 3 ]
The prefix is: PREFIX-A
The values are: 1, 2, 3

实际结果:

AAA contructor [ 1, 2, 3 ]
The prefix is: PREFIX-A
AAA contructor undefined

/Users/amaurymartiny/Workspaces/test-array/a.ts:7
    this.push(...values);
         ^
TypeError: Cannot read property 'Symbol(Symbol.iterator)' of this.push
    at new AAA (/Users/amaurymartiny/Workspaces/test-array/a.ts:7:10)
    at AAA.map (<anonymous>)
    at AAA.logMe (/Users/amaurymartiny/Workspaces/test-array/a.ts:13:41)
    at Object.<anonymous> (/Users/amaurymartiny/Workspaces/test-array/a.ts:18:3)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Module.m._compile (/Users/amaurymartiny/Workspaces/test-array/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/amaurymartiny/Workspaces/test-array/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)

这让我很奇怪,为什么我调用this.map时又调用了构造函数?

TypeScript 3.1.3。节点JS 10.12.0。我已经实现了this related thread

【问题讨论】:

  • 您是否打算在Array 上调用本机map 函数?这不是返回一个新数组吗?
  • 你正在记录电话console.log 你不是要写console.log('The values are:', this.join(", "))
  • @FrankModica 是的,我打算调用原生地图。是的,它返回一个新的 Array,所以应该调用 Array 的构造函数,而不是 AAA 的构造函数。
  • @Motti 已修复。我实际上希望子类使用map 方法,
  • 哦,你是对的,很有趣!

标签: javascript typescript


【解决方案1】:

试试这个。它对我有用。

class Collection extends Array<xxx> {    
   constructor(documents: Array<xxx> | number) {
      if(documents instanceof Array) super(...documents);
      else super(documents);
      Object.setPrototypeOf(this, Object.create(Collection.prototype));
   }      
   public get aMethodUsingMapAsExample(): string[] {
      // this.map invokes the constructor with the length passed in as argument
      var types = this.map(e => e.documentType);
      types = types.sort();
      return types;
   }  
}

解释:原生数组构造函数有2个重载。您必须在扩展课程中同时支持它们。这是因为 this.map 在幕后创建了一个新数组,从而调用具有数组长度的构造函数。

  • ArrayConstructor(...items: any[]):这里你必须调用spread运算符才能正确构造数组
  • ArrayConstructor(数组长度:数字)。对 number 类型的对象调用扩展运算符将抛出异常

【讨论】:

  • 如果您传递一个包含一个 number 类型的单个元素的数组,则会出现异常,它将将该单个元素视为数组解决方案的长度 if (arr instanceof Array) { if (arr.长度 == 1) { super(); this.push(arr[0]); } 其他 { 超级(...arr); } }
猜你喜欢
  • 2019-10-17
  • 2019-11-13
  • 1970-01-01
  • 2016-11-21
  • 2021-10-17
  • 1970-01-01
  • 2018-05-26
  • 2019-02-12
  • 2021-10-25
相关资源
最近更新 更多