ES6 Singleton与实例化一次类

时间:2018-01-21 12:04:22

标签: javascript es6-class

我看到使用ES6类使用单例模式的模式,我想知道为什么我会使用它们而不是仅仅实例化文件底部的类并导出实例。这样做有什么负面的缺点吗?例如:

ES6导出实例:

import Constants from '../constants';

class _API {
  constructor() {
    this.url = Constants.API_URL;
  }

  getCities() {
    return fetch(this.url, { method: 'get' })
      .then(response => response.json());
  }
}

const API = new _API();
export default API;

用法:

import API from './services/api-service'

使用以下Singleton模式有什么区别?是否有任何理由使用另一个?我真的更好奇,知道我给出的第一个例子是否有我不知道的问题。

单身人士模式:

import Constants from '../constants';

let instance = null;

class API {
  constructor() {

    if(!instance){
      instance = this;
    }

    this.url = Constants.API_URL;

    return instance;
  }

  getCities() {
    return fetch(this.url, { method: 'get' })
      .then(response => response.json());
  }
}

export default API;

用法:

import API from './services/api-service';

let api = new API()

4 个答案:

答案 0 :(得分:29)

我不推荐。这完全过于复杂。如果您只需要一个对象do not use the class syntax!只是去

import Constants from '../constants';

export default {
  url: Constants.API_URL,
  getCities() {
    return fetch(this.url, { method: 'get' }).then(response => response.json());
  }
};

import API from './services/api-service'

even simpler

import Constants from '../constants';

export const url = Constants.API_URL;
export function getCities() {
  return fetch(url, { method: 'get' }).then(response => response.json());
}

import * as API from './services/api-service'

答案 1 :(得分:12)

区别在于你是否想要测试。

假设你有api.spec.js测试文件。并且你的API thingy有一个依赖,就像那些常量。

具体来说,两个版本中的构造函数都有一个参数,即Constants导入。

所以你的构造函数看起来像这样:

class API {
    constructor(constants) {
      this.API_URL = constants.API_URL;
    }
    ...
}



// single-instance method first
import API from './api';
describe('Single Instance', () => {
    it('should take Constants as parameter', () => {
        const mockConstants = {
            API_URL: "fake_url"
        }
        const api = new API(mockConstants); // all good, you provided mock here.
    });
});

现在,通过导出实例,没有嘲笑。

import API from './api';
describe('Singleton', () => {
    it('should let us mock the constants somehow', () => {
        const mockConstants = {
            API_URL: "fake_url"
        }
        // erm... now what?
    });
});

通过导出实例化对象,您可以(轻松而安全地)更改其行为。

答案 2 :(得分:0)

两者都做同样的事情。第一个是100%es6。第二种是在es6中重写的旧方式。

我会随时选择第一个,新开发者不会理解为什么你必须使事情复杂化,如果es6是他们首先开始的那个

答案 3 :(得分:0)

两者都是不同的方式。 导出如下所示的类

const APIobj = new _API();
export default APIobj;   //shortcut=> export new _API()

然后在多个文件中进行如下所示的导入将指向同一实例以及一种创建Singleton模式的方法。

import APIobj from './services/api-service'

直接导出类的另一种方法不是像我们要导入的文件中那样单例,我们需要更新类,这将为每次更新创建一个单独的实例 仅导出类:

export default API;

导入课程并进行更新

import API from './services/api-service';
let api = new API()