【问题标题】:How do I pass constructor parameters to imported class in ECMAScript 6?如何将构造函数参数传递给 ECMAScript 6 中的导入类?
【发布时间】:2020-12-19 14:01:04
【问题描述】:

如果我将一个类导入到其他脚本中,如何以 ES6 语法将参数传递给该类构造函数?

我想做这样的事情。我已经看到了各种建议,例如包装函数或使用工厂模式,但是有没有更简洁的方法呢?

// This is sudo code
import SomeClass from './SomeClassPath';
var thing = SomeClass(params);

【问题讨论】:

  • 不确定您要做什么。它总是new SomeClass(params)(它是一个单一的参数,顺便说一句)。请准确解释您要做什么。
  • 嗯,我认为对某些类使用 import 会提供该类的单例实例,无论 import 被调用多少次。这不是真的吗?
  • 这适用于您要导入的任何内容。类实例不会自动成为单例。它只执行一次导入的文件,这就是“单例”事情的发生方式。除非您使用它来导出像 export const someClassInstance = new SomeClass 这样的单例,否则这不是问题。
  • 我认为你的意思是伪代码。还是那是文字游戏? :-)

标签: ecmascript-6


【解决方案1】:

我看到你的问题有些混乱,所以让我澄清一下。

在 ES6 中,您可能知道在需要导出模块时有两种策略。您可以使用默认导出多个导出。让我们举一个非常基本的例子(console 周围的一个简单记录器):

function info(msg) {
  console.info(`[Info] ${msg}`);
}

function error(msg) {
  console.error(`[Error] ${msg)`);
}

默认导出

在这里我们必须对函数进行分组。在 JavaScript 中最惯用的方法是使用对象字面量(参见 Revealing Module Pattern):

export default {
  info(msg) {
    console.info(`[Info] ${msg}`);
  },
  error(msg) {
    console.error(`[Error] ${msg}`);
  }
};

然后,在我们的客户端代码中,我们将像这样使用这个模块:

import logger from './logger'

logger.info('Hello!');
logger.error('Oops!');

多个导出

这里我们可以独立导出我们的函数:

export function info(msg) {
  console.info(`[Info] ${msg}`);
}

export function error(msg) {
  console.error(`[Error] ${msg}`);
}

然后,在我们的客户端代码中,我们将像这样使用这个模块:

import {info, error} from './logger'

info('Hello!');
error('Oops!');

完成。

我建议您了解 ES6 模块系统如何与我们的功能示例一起工作。与类完全一样...


单例?

通过阅读 cmets,我发现了另一个需要澄清的困惑:Singleton

Singleton 是一种设计模式,它可以使类实例化一次。现在想象我们的类如下:

export default class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
};

我们可以这样使用它:

import Person from './Person';

let me = new Person('Baptiste', 'Vannesson'),
    you = new Person('David', 'Choi');

console.log(Object.is(me, you)); // false, so there are two instances of Person
console.log(me.firstName, me.lastName);  // Baptiste Vannesson
console.log(you.firstName, you.lastName); // David Choi

如您所见,Person 与 Singleton 无关!这将是一个具有以下 Java 启发实现的单例:

export default (() => {

  class Person {
    // Private constructor
    constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
  }

  return {
    // Public static factory method
    getInstance(firstName, lastName) {
      if (!Person.instance) {
        Person.instance = new Person(firstName, lastName);
      }
      return Person.instance;
    }
  };

})();

客户端代码:

import Person from './Person';

let me = Person.getInstance('Baptiste', 'Vannesson'),
    you = Person.getInstance('David', 'Choi');

console.log(Object.is(me, you)); // true, so there is only one instance
console.log(me.firstName, me.lastName); // Baptiste Vannesson
console.log(you.firstName, you.lastName); // Baptiste Vannesson (still me!)

为简单起见,您可能更喜欢直接导出实例:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
};

export default new Person('David', 'Choi');

客户端代码:

import person from './person';

// Person is not a constructor but a simple instance
let me = person,
    you = person;

console.log(Object.is(me, you)); // true
console.log(me.firstName, me.lastName); // David Choi
console.log(you.firstName, you.lastName); // David Choi

如果你这样做,使用对象字面量会更简单:

export default {
  firstName: 'David',
  lastName: 'Choi'
};

这里的客户端代码没有变化。

【讨论】:

    【解决方案2】:

    将参数传递给您的 es6 模块非常简单直接。 做这个简单的事情。

    // This is sudo code
    require('./SomeClassPath.js')(param);
    

    然后在模块文件 SomeClassPath.js 里面做这个

    module.exports = function(param) {
     ....     
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2015-10-11
      • 1970-01-01
      • 2022-01-13
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多