好的,我意识到这可以被认为是主观的,但是我试图更好地理解在编写仅公开公开需要的模块时如何考虑范围。我有一个字符串实用程序,下面已经将其编写为对象文字:
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模块并公开
getSubstring
和getSubstrings
方法,但是如果要这样做:module.exports = {
all: substrings.getSubstrings,
one: substrings.getSubstring
}
由于使用
this
会出现错误。我意识到,如果将this
替换为对象var name substrings
以直接引用它,则它可以工作。我也可以将其重构为一个较大的函数或较小的函数,然后导出我需要的2个函数。我正在努力以正确的方式学习事物,并且正在为应该如何思考上下文而苦苦挣扎。我了解
this
在这里如何变化,但是我觉得我并没有完全理解在构造代码时应该如何考虑上下文。有没有更优雅的解决方案,可以使用未编写为分离私有方法和私有方法的代码公开方法?
最佳答案
一个简单的解决方案是将导出的函数bind
到exports
对象内的正确调用上下文:
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/