使用来自不同模块的对象

Using object from different module

我有下面的代码,它是解析对象并像下面那样为它提供 getter,这是有效的,问题是我想从不同的模块访问这个对象并避免再次解析,如何才能我在没有定义全局变量的情况下这样做?

var ymlParser = require('yamljs');

function ymlParse(src) {
    if (!(this instanceof ymlParse)) return new ymlParse(src);
    this.data = ymlParser.parse(src);
}

ymlParse.prototype = {
    getA: function () {
        return this.data.default_A;
    },

    getB: function () {
        return this.data._B;
    }
};

module.exports = ymlParse;

假设我想从模块 A 访问 A 并从模块 B 访问 B,我如何在调用 getB 时不再次发送 src 来做到这一点,因为当我调用 getA 我已经传递了 src...

您可以在 ymlParse class 中进行缓存(它的设计类似于 class,不是吗?)。 只存储 src 个对象和解析结果。如果 ymlParse 将使用缓存的 src 执行,仅 return 存储结果而不解析。

尝试像这样更改您的代码:

var ymlParser = require('yamljs');

function ymlParse(src) {
    if (!(this instanceof ymlParse)) return new ymlParse(src);
    if (this.cache[src]) {
        this.data = this.cache[src];
    } else {
        this.data = ymlParser.parse(src);
        this.cache[src] = this.data;
    }
}

ymlParse.prototype = {
    cache: {},

    getA: function () {
        return this.data.default_A;
    },

    getB: function () {
        return this.data._B;
    }
};

module.exports = ymlParse;

请注意,我没有使用 this.data 对象的深拷贝。如果它不是只读的,它可能会导致一些问题。

您可以使用记忆模式 - http://addyosmani.com/blog/faster-javascript-memoization/。其他答案中实施的一个问题不是散列参数。所以你应该有这样的东西:

var ymlParser = require('yamljs');

function ymlParse(src) {
  var hash = JSON.stringify(src);

  if (!(this instanceof ymlParse)) return new ymlParse(src);
  if (this.cache[hash]) {
    this.data = this.cache[hash];
  } else {
    this.data = ymlParser.parse(src);
    this.cache[hash] = this.data;
  }
}

ymlParse.prototype = {
  cache: {},

  getA: function () {
    return this.data.default_A;
  },

  getB: function () {
    return this.data._B;
  }
};

module.exports = ymlParse;

仔细查看 JSON.stringify 方法。您必须在此处实现哈希算法,将哈希与 src 数据相关联作为唯一标识符。通常是 JSON.stringify 但您可以使用自己的。

或者另一种函数式的解决方案:

var _ = require('lodash');
var ymlParser = require('yamljs');

function ymlParse(src) {
  var result = ymlParser.parse(src);

  return {
    getA: function() {
      return result.default_A;
    },
    getB: function() {
      return result._B;
    }
  };
}

module.exports = _.memoize(ymlParse);

用法相同,你只需调用导出的函数即可。