好的,我意识到这可以被认为是主观的,但是我试图更好地理解在编写仅公开公开需要的模块时如何考虑范围。我有一个字符串实用程序,下面已经将其编写为对象文字:

const substrings = {
  query: {},
  text: "",
  results: [],

  exists: function (index) {
    const exists = index >= 0

    return exists
  },

  check: function () {
    const q = this.query
    const start = q.openIndex
    const stop = q.closeIndex

    if (q.hasOpen && !q.hasClose) {
      console.log("Missing closing delimiter.")
    }
    if (!q.hasOpen && q.hasClose) {
      console.log("Missing opening delimiter.")
    }
    if (q.hasOpen && q.hasClose && start > stop) {
      console.log("Closing delimiter found before opening.")
    }
    if (!q.hasOpen && !q.hasClose && this.results.length == 0) {
      console.log("No results found.")
    }

    const order = start < stop
    const check = q.hasOpen && q.hasClose && order

    return check
  },

  update: function () {
    const q = this.query
    const text = this.text

    q.before = this.text.indexOf(q.open)
    q.start = q.before + q.open.length

    this.text = text.slice(q.start, text.length)

    q.stop = this.text.indexOf(q.close)
    q.after = q.stop + q.close.length
    q.openIndex = q.before
    q.closeIndex = q.before + q.stop
    q.hasOpen = this.exists(q.openIndex)
    q.hasClose = this.exists(q.stop)

    const newPosition = q.start + q.after

    q.position = q.position + newPosition

    this.query = q
  },

  substrings: function () {
    const q = this.query

    const current = this.text.slice(0, q.stop)
    const fullLength = this.text.length

    this.text = this.text.slice(q.after, fullLength)

    this.results.push(current)

    this.update()

    if (this.check()) {
      this.substrings()
    }
  },

  init: function (open, close, text) {
    this.results = []
    this.query = {
      open,
      close,
      position: 0,
    }

    this.text = text
    this.update()
  },

  getSubstrings: function (open, close, text) {
    this.init(open, close, text)

    if (this.check()) {
      this.substrings()
      return this.results
    }
  },

  getSubstring: function (open, close, text) {
    this.init(open, close, text)

    if (this.check()) {
      return this.text.slice(0, this.query.stop)
    }
  }

}


我想将其用作Node模块并公开getSubstringgetSubstrings方法,但是如果要这样做:

module.exports = {
  all: substrings.getSubstrings,
  one: substrings.getSubstring
}


由于使用this会出现错误。我意识到,如果将this替换为对象var name substrings以直接引用它,则它可以工作。我也可以将其重构为一个较大的函数或较小的函数,然后导出我需要的2个函数。

我正在努力以正确的方式学习事物,并且正在为应该如何思考上下文而苦苦挣扎。我了解this在这里如何变化,但是我觉得我并没有完全理解在构造代码时应该如何考虑上下文。

有没有更优雅的解决方案,可以使用未编写为分离私有方法和私有方法的代码公开方法?

最佳答案

一个简单的解决方案是将导出的函数bindexports对象内的正确调用上下文:

module.exports = {
  all: substrings.getSubstrings.bind(substrings),
  one: substrings.getSubstring.bind(substrings)
}


就个人而言,在这种情况下,我更喜欢使用显示模块模式而不是对象文字。使用显示模块模式,创建一个IIFE,该IIFE返回所需的函数,并引用局部变量而不是this上的属性。例如:

const { getSubstrings, getSubstring } = (() => {
  let query = {}
  let text = ''
  let results = []
  function exists(index) {
    return index >= 0
  }
  function check() {
    const q = query;
    // ...
  }
  ...
  function getSubstrings(open, close, text) {
  }
  ...
  return { getSubstrings, getSubstring };
})();

module.exports = {
  all: getSubstrings,
  one: getSubstring
}


这是基于观点的,但是当没有任何this引用值得担心时,代码可以更容易阅读。

关于javascript - 在JS模块中公开对象方法时,如何管理上下文?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51645328/

10-13 00:37