【问题标题】:"Is not a function" error with custom class method自定义类方法出现“不是函数”错误
【发布时间】:2021-12-17 00:57:45
【问题描述】:

我的任务是将 A 类型的数组转换为具有 Person 类对象的对象。我成功地做到了,但我无法使用转换后的数组调用 Person 类的方法。这是我无法理解的,因为所有 console.log 检查都表明一切都转换得很好,并且 b 包含 Person 类的实例,而不仅仅是包含数据的数组。

所以我的代码在这里展示:

import crypto from "crypto"

type A = Array<[string, number, string]>;

type B = {
    [id: string]: Person
}

export class Person {
    _id: string; // must be unique
    age: number;
    name: string;
    city: string;

    constructor(name: string, age: number, city: string) {
        this._id = Person.generateUniqueID(12);
        this.age = age
        this.name = name
        this.city = city
    }

    private static generateUniqueID(len: number): string {
        return crypto.randomBytes(Math.ceil(len/2))
            .toString('hex')
            .slice(0, len);
    }

    public tellUsAboutYourself(): string {
        console.log(
            `Person with unique id = ${this._id} says:\n
             Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.`
        );
        return `Person with unique id = ${this._id} says:\n Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.`
    }
}

export const a: A = [
    ['name1', 24, 'city1'],
    ['name2', 33, 'city2'],
    ['name3', 61, 'city3'],
    ['name4', 60, 'city4']
];

export const b: B = a.reduce(function (value: any, [name, age, city]) {
    let persona = new Person(name, age, city);
    value[persona._id] = [persona.name, persona.age, persona.city]
    return value;
}, {});

a 成功转换为 b,b 的控制台日志如下所示:

{
  'd85750baf38f': [ 'name1', 24, 'city1' ],
  '1f8fc00c6762': [ 'name2', 33, 'city2' ],
  '8bac45ed719b': [ 'name3', 61, 'city3' ],
  '1f00fa9086a2': [ 'name4', 60, 'city4' ]
}

Object.keys(b) 的控制台日志是:

[ 'd85750baf38f', '1f8fc00c6762', '8bac45ed719b', '1f00fa9086a2' ]

我怎么会这样做:

Object.keys(b).forEach(key => {
    b[key].tellUsAboutYourself();
})

在 tsc 编译器中它说:

    exports.b[key].tellUsAboutYourself();
                   ^

TypeError: exports.b[key].tellUsAboutYourself is not a function

【问题讨论】:

    标签: javascript arrays typescript for-loop


    【解决方案1】:

    当你这样做时

    value[persona._id] = [persona.name, persona.age, persona.city]
    

    在 de reduce 中,您并没有保存 Person 对象,您只是将其属性放在一个数组中。这个数组不会有 Person 的方法。你应该这样做

    value[persona._id] = persona
    

    改为。

    【讨论】:

      【解决方案2】:

      您的b 对象没有Person() 的任何实例。您只是在粘贴非方法属性。

      如下所示,b 中的任何属性都没有对象实例,而只是一个数组。

      {
        'd85750baf38f': [ 'name1', 24, 'city1' ],
        '1f8fc00c6762': [ 'name2', 33, 'city2' ],
        '8bac45ed719b': [ 'name3', 61, 'city3' ],
        '1f00fa9086a2': [ 'name4', 60, 'city4' ]
      }
      
      

      当您执行以下操作时,b 的每个属性都将是一个 Person 实例,并且将具有方法 - tellUsAboutYourself

      export const b: B = a.reduce(function (value: any, [name, age, city]) {
          let persona = new Person(name, age, city);
          value[persona._id] = persona;
          return value;
      }, {});
      
      

      编写最终循环的更好方法是使用Object.values(),这样您就可以直接获得各个值:

      Object.values(b).forEach(obj => {
          obj.tellUsAboutYourself();
      })
      
      

      但这只是一种改进。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-16
        • 1970-01-01
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多