Javascript JS模块模式保留值
我创建了一个分析字符串的模块。它计算例如字符串中字母Javascript JS模块模式保留值,javascript,Javascript,我创建了一个分析字符串的模块。它计算例如字符串中字母o的出现次数: export default (function () { var analysis = { occurencesOfO: 0, }; var util = { countOs: function(input) { for (let i = 0; i < input.length; i++) { analysi
o
的出现次数:
export default (function () {
var analysis = {
occurencesOfO: 0,
};
var util = {
countOs: function(input) {
for (let i = 0; i < input.length; i++) {
analysis.occurencesOfO += input[i] === 'o' ? 1 : 0;
}
},
}
return {
analyze: function (input) {
util.countOs(input);
return analysis.occurencesOfO;
}
};
})();
我本以为
analysis
会被重置,但事实并非如此。为什么?我该如何改变这一点呢?您看到这种行为是因为,无论是有意还是无意,您正在使用一种微妙但重要的JavaScript特性,名为。闭包是引用自身内部范围之外的变量的函数。这些变量会自动绑定到函数中,但不会在每次调用函数时都实例化为新的变量。如果函数之外的内容修改了closured变量,那么这些更改将在下次函数运行时反映出来
这是非常抽象的,但它是您示例中发生的事情的核心。在分析功能中:
analyze:函数(输入){
util.countOs(输入);
返回分析.OccurnceSofo;
}
您可以参考变量分析
。但是,该变量不是函数本身的局部变量!相反,它来自模块更广泛的上下文。这意味着当analyze
返回时,analysis
不会被垃圾收集,也不会丢失其新值。该值将保留到下次运行该函数时
为了防止出现这种情况,我将采取的方法是将analysis
设置为analysis
函数中的变量范围:
导出默认值(函数(){
var util={
countOs:函数(输入){
风险价值分析={
发生时间:0
};
for(设i=0;i
每次调用函数时,您都在对foo.bar进行变异,我认为它会做这样的事情是合乎逻辑的。你能精确描述你的用例吗?请看修改后的问题。所以它可以计算,但是,如果我理解正确,你想要一种方法来防止输入一个已经分析过的字符串。您能否在模块内部保留一个包含以前输入的数组,以便在已经看到输入时不会求和?A)如果您不希望使用共享状态的单例,请不要使用模块模式B)不要放置var foo={bar:0,}如果您想为每个analyze
callI创建一个新的,请在模块范围内使用code>,我希望重新措辞,使问题更清楚。但基本上Bergi明白了我的意思。我不希望函数调用之间共享状态。我如何做到这一点?这会抛出一个错误,analysis
没有定义。啊,好的一点,countOs
需要一种引用analysis
的方法。我将进行编辑。@Kurztipp我的答案现在看起来怎么样?
import Analysis from './Analysis';
//...
let s = 'foobar';
let result = Analysis.analyze(s);
console.log('should yield: 2 but yields: ' + result);
// should yield: 2 but yields: 2
s = 'foo bar';
result = Analysis.analyze('fooo bar');
console.log('should yield: 3 but yields: ' + result);
// should yield: 3 but yields: 5
s = 'foo bar foobar';
result = Analysis.analyze('foo bar foobar');
console.log('should yield: 4 but yields: ' + result);
// should yield: 4 but yields: 9