Javascript 在其他类中注入类

Javascript 在其他类中注入类,javascript,class,oop,Javascript,Class,Oop,我有一个Tag类和一个TagCollection类来存储多个标记。现在,TagRepository类需要构造一个新的Tag对象来返回。但是,当我尝试在TagRepository中创建一个新的标记时,它返回一个错误: 未定义标记 这就是我在主JavaScript文件中包含所有类的方式: const Tag = require('./class/Tag.js'); const TagCollection = require('./class/TagCollection.js'); const Tag

我有一个
Tag
类和一个
TagCollection
类来存储多个标记。现在,
TagRepository
类需要构造一个新的
Tag
对象来返回。但是,当我尝试在
TagRepository
中创建一个新的
标记时,它返回一个错误:

未定义标记

这就是我在主JavaScript文件中包含所有类的方式:

const Tag = require('./class/Tag.js');
const TagCollection = require('./class/TagCollection.js');
const TagRepository = require('./repository/TagRepository.js');
我们通常如何处理这个问题?我可以将所需的类包含在需要它们的类的构造函数中。但当我必须包含多个类时,这看起来很混乱

我唯一能想到的另一个解决办法是让所需的课程全球化,在线阅读似乎被认为是不好的做法。下面我列出了所有的课程

Tag.js

module.exports = class Tag {
  constructor() {
    this.id;
    this.name;
  }

  setId(id) {
    this.id = id;
  }

  setName(name) {
    this.name = name;
  }

  getId() {
    return this.id;
  }

  getName() {
    return this.name;
  }
}
module.exports = class TagCollection {
  constructor() {
    this.tags = [];
  }

  addTag(tag) {
    this.tags.push(tag);   
  }

  setTags(tags) {
    this.tags = tags;
  }

  getTags(tags) {
    return this.tags;
  }
}
module.exports = class TagRepository {
  constructor(conn) {
    this.conn = conn;
  }

  getAll(callback) {
    let tempTagCollection = new TagCollection;

    this.conn.query(`SELECT \`id\`, \`name\` FROM \`tag\` WHERE 1`, function (error, tags) {
      tags.forEach((tag) => {
        //Create single tag 
        let tempTag = new Tag;

        //Set properties
        tempTag.setName(tag.name);
        tempTag.setId(tag.id);

        //Add single tag to collection
        tempTagCollection.addTag(tempTag);
      })

      callback(tempTagCollection);
    })
  }
}
TagCollection.js

module.exports = class Tag {
  constructor() {
    this.id;
    this.name;
  }

  setId(id) {
    this.id = id;
  }

  setName(name) {
    this.name = name;
  }

  getId() {
    return this.id;
  }

  getName() {
    return this.name;
  }
}
module.exports = class TagCollection {
  constructor() {
    this.tags = [];
  }

  addTag(tag) {
    this.tags.push(tag);   
  }

  setTags(tags) {
    this.tags = tags;
  }

  getTags(tags) {
    return this.tags;
  }
}
module.exports = class TagRepository {
  constructor(conn) {
    this.conn = conn;
  }

  getAll(callback) {
    let tempTagCollection = new TagCollection;

    this.conn.query(`SELECT \`id\`, \`name\` FROM \`tag\` WHERE 1`, function (error, tags) {
      tags.forEach((tag) => {
        //Create single tag 
        let tempTag = new Tag;

        //Set properties
        tempTag.setName(tag.name);
        tempTag.setId(tag.id);

        //Add single tag to collection
        tempTagCollection.addTag(tempTag);
      })

      callback(tempTagCollection);
    })
  }
}
TagRepository.js

module.exports = class Tag {
  constructor() {
    this.id;
    this.name;
  }

  setId(id) {
    this.id = id;
  }

  setName(name) {
    this.name = name;
  }

  getId() {
    return this.id;
  }

  getName() {
    return this.name;
  }
}
module.exports = class TagCollection {
  constructor() {
    this.tags = [];
  }

  addTag(tag) {
    this.tags.push(tag);   
  }

  setTags(tags) {
    this.tags = tags;
  }

  getTags(tags) {
    return this.tags;
  }
}
module.exports = class TagRepository {
  constructor(conn) {
    this.conn = conn;
  }

  getAll(callback) {
    let tempTagCollection = new TagCollection;

    this.conn.query(`SELECT \`id\`, \`name\` FROM \`tag\` WHERE 1`, function (error, tags) {
      tags.forEach((tag) => {
        //Create single tag 
        let tempTag = new Tag;

        //Set properties
        tempTag.setName(tag.name);
        tempTag.setId(tag.id);

        //Add single tag to collection
        tempTagCollection.addTag(tempTag);
      })

      callback(tempTagCollection);
    })
  }
}

你需要在你需要的每个文件中“要求”你需要的每个类,所以不像(例如)PHP,你不能在每个程序中只要求一次所有内容。

你需要在每个文件中“要求”你需要的每个类,所以不像(例如)PHP,你不能在每个程序中只要求一次所有内容

我唯一能想到的另一个解决办法是让所需的课程全球化,在线阅读似乎被认为是不好的做法

您是对的,应该尽可能避免使用全局变量,因为它会导致代码脆弱且难以调试

您可以将每个文件视为一个模块。我个人喜欢每个类保留一个文件,这样我就可以将类本身视为一个模块。在每个模块中,您应该
要求所依赖的每个类

因此,我将使用一个经典的动物/猫/狗示例:

//Animal.js
module.exports = class Animal { ... }

//Cat.js
const Animal = require('./Animal');
class Cat extends Animal { ... }

//Dog
const Animal = require('./Dog');
class Dog extends Animal { ... }
在NodeJS中,即使
Cat
Dog
都需要
Animal
,Animal.js也只执行一次。因此,需要
Animal
的每个模块将获得相同的
Animal

我可以将所需的类包含在需要它们的类的构造函数中

我也会避免这样做。在构造函数中使用
require
,即使
require
'd文件只会在第一次需要时执行该文件,它仍然会通过节点文件解析算法,这是一个昂贵的过程,可能会导致性能瓶颈。通常,最好将
require
语句置于构造函数或函数之外。将它们放在文件的顶部,当应用程序加载时,所有requires都将在这里运行一次

正如您现在在TagRepository中看到的,它需要两个类,Tag和TagCollection类,我该如何处理

在TagRepository.js中,您只需要有2条include语句,每个文件一条,见下文

const Tag = require('./Tag');
const TagCollection = require('./TagCollection.js');

// Both Tag and TagCollection is now usable

class TagRepository { ... }
有关NodeJS模块的更多信息,请参见此处

我唯一能想到的另一个解决办法是让所需的课程全球化,在线阅读似乎被认为是不好的做法

您是对的,应该尽可能避免使用全局变量,因为它会导致代码脆弱且难以调试

您可以将每个文件视为一个模块。我个人喜欢每个类保留一个文件,这样我就可以将类本身视为一个模块。在每个模块中,您应该
要求所依赖的每个类

因此,我将使用一个经典的动物/猫/狗示例:

//Animal.js
module.exports = class Animal { ... }

//Cat.js
const Animal = require('./Animal');
class Cat extends Animal { ... }

//Dog
const Animal = require('./Dog');
class Dog extends Animal { ... }
在NodeJS中,即使
Cat
Dog
都需要
Animal
,Animal.js也只执行一次。因此,需要
Animal
的每个模块将获得相同的
Animal

我可以将所需的类包含在需要它们的类的构造函数中

我也会避免这样做。在构造函数中使用
require
,即使
require
'd文件只会在第一次需要时执行该文件,它仍然会通过节点文件解析算法,这是一个昂贵的过程,可能会导致性能瓶颈。通常,最好将
require
语句置于构造函数或函数之外。将它们放在文件的顶部,当应用程序加载时,所有requires都将在这里运行一次

正如您现在在TagRepository中看到的,它需要两个类,Tag和TagCollection类,我该如何处理

在TagRepository.js中,您只需要有2条include语句,每个文件一条,见下文

const Tag = require('./Tag');
const TagCollection = require('./TagCollection.js');

// Both Tag and TagCollection is now usable

class TagRepository { ... }
有关NodeJS模块的更多信息,请参见此处


如果您能提供代码,我认为这将有助于我们理解问题以及如何解决问题。您能提供您的实际代码吗?如果您在TagRepository.js中使用Tag.js,您可能需要它。@NTR我已经添加了code@sn3p我现在已经包含了代码,您应该将
const Tag=require('./class/Tag.js');const TagCollection=require('./class/TagCollection.js')TagRepository.js文件中的行。如果您能提供代码,我认为这将有助于我们理解问题以及如何解决问题。您能提供您的实际代码吗?如果您在TagRepository.js中使用Tag.js,您可能需要它。@NTR我已经添加了code@sn3p我现在已经包含了代码,您应该将
const Tag=require('./class/Tag.js');const TagCollection=require('./class/TagCollection.js')行。我明白了,在类中我需要在哪里使用其他外部类?我刚刚从另一个答案中了解到,在构造函数中包含require并不理想。在每个需要它的文件中,都包含文件顶部的所有内容。我明白了,在类中,我在哪里需要其他外部类?我刚刚从另一个答案中学到,在c语言中包含require并不理想