我正在编写我的第一个javascript模块,并且我不了解范围变量。这是我的模块:
var Module = (function () {
var myString ='a';
var changeString = function () {
myString ='b';
console.log(myString);
};
return {
changeString: changeString,
myString:myString
};
})();
现在,如果我这样做:
Module.myString; // returns 'a'
Module.changeString(); // returns 'b'
Module.myString; // returns 'a'
对我来说,最后一个命令应该返回' b'因为我用changeString方法改变了myString。我不明白为什么,因为myString是在changeString方法之外声明的,所以范围似乎没问题。我想了解为什么它的行为如此,以及如何创建一个覆盖我的变量值的方法。 提前谢谢。
答案 0 :(得分:4)
这会在创建对象时生成myString
的副本:
return {
changeString: changeString,
myString:myString
}
您可以使用getter动态返回本地变量,这将为您提供所需的行为:
return {
changeString: changeString,
get myString() {
return myString;
}
}
完整示例:
var Module = (function () {
var myString ='a';
var changeString = function () {
myString ='b';
console.log(myString);
};
return {
changeString: changeString,
get myString() {
return myString;
}
}
})();
console.log( Module.myString );
Module.changeString();
console.log( Module.myString );

答案 1 :(得分:3)
匿名函数只执行一次,因此它返回的对象也只被评估一次:它是一个具有字符串属性myString
的对象,它是一个原始值 - 如果是变量myString
稍后会更改。
如果你想要你想要的行为,那么你应该在Module中保留一个引用你返回的对象,然后当string属性需要改变时 mutate 该对象:
var Module = (function () {
var changeString = function () {
obj.myString = 'b'; // mutation of obj!
console.log(obj.myString);
};
var obj = {
changeString: changeString,
myString: 'a';
};
return obj; // we have a reference to this object
})();
答案 2 :(得分:3)
正如在其他答案中所说,因为myString
是一个原语,所以它的值从作用域复制到返回的匿名对象的成员值。要从myString
方法访问外部可用的changeString()
副本,您可以使用Module
关键字引用分配给this
的匿名对象:
var Module = (function() {
var myString = 'a';
var changeString = function() {
// `Module.changeString()` causes `this === Module` inside here
this.myString = 'b';
};
return {
changeString: changeString,
myString: myString
};
})();
console.log(Module.myString); // returns 'a'
Module.changeString();
console.log(Module.myString); // returns 'b'

使用ES6语法,您可以使用一些快捷方式来简化此方法:
var Module = (() => {
let myString = 'a';
return {
// ES6 for `myString: myString,`
myString,
// ES6 for `changeString: function () {`
changeString () {
this.myString = 'b';
}
};
})();
console.log(Module.myString); // returns 'a'
Module.changeString();
console.log(Module.myString); // returns 'b'

答案 3 :(得分:1)
您会看到此行为,因为您return
是一个新对象。
字符串myString
被复制,因为它是原始值。
您可以通过一些调整来实现目标:
var Module = function() {
var myString = 'a';
this.changeString = function() {
myString = 'b';
};
this.getString = function() {
return myString;
};
};
var mod = new Module;
console.log(mod.getString()); // a
mod.changeString();
console.log(mod.getString()); // b