我正在研究一些设计模式(Module Reveal 和 Singleton 模式),其中包含按预期工作的基本内容,例如与多个共享的两个实用函数对象,其中一个更新字符串的值,另一个复制字符串的值。
当我将字符串转换为数组时发生了意想不到的事情,期望它通过引用传递,但由于某种原因它没有:
Test.js
(function(win){
var MainObj=(function(){
var _alls = Object.create(null);
function u_updateVal(){
this.arr = ["up", "da", "ted"];
}
function u_copyVal(oName, prop){
this[prop] = _alls[oName][prop];
}
function init(oName){
if(typeof _alls[oName]==="undefined"){
_alls[oName] = {
arr : ["def", "ault"],
updateVal : u_updateVal,
copyVal : u_copyVal
};
}
return _alls[oName];
}
return {
init : init
};
})();
if(!win.MainObj){
win.MainObj = MainObj;
}
})(window);
来自 HTML 的 plain-js,取决于:Test.js
if(!window.MainObj){
console.log("Error: MainObj is not defined");
}else{
var a = MainObj.init("AA");
var b = MainObj.init("BB");
var c = MainObj.init("CC");
b.updateVal();
c.copyVal("BB", "arr");
b.arr=["over", "written"];
console.log(a.arr.join()); //def,ault
console.log(b.arr.join()); //over,written
console.log(c.arr.join()); //up,da,ted (I expected "over,written")
}
我希望 c.arr
指向与 b.arr
相同的引用,因为数组的副本没有像 splice/slice/这样的任何预防措施JSONstringify/等
为了改变现状,我创建了另一个函数来通过 b.otherUpdateVal();
更新值,而不是 b.arr = ["over", "written"] ;
,希望它与闭包有关,超出了我目前对它们的理解,但这仍然给出了相同的结果。
我似乎无法理解为什么这些数组没有通过引用传递(即使没有采取特殊措施来防止这种情况发生)。有没有想过为什么会发生这种情况?
编辑: 是的,这只是一个愚蠢的疏忽,认为重新分配 b 会影响已完成的 c 引用。如果您使用 b.arr.push(".");
或排序,或任何实际上不会创建全新数组的东西,您确实会看到它们都受到影响。
最佳答案
让我们逐步了解会发生什么。
var a = MainObj.init("AA");
var b = MainObj.init("BB");
var c = MainObj.init("CC");
完成这一步后,您就拥有了。
a.arr; // ["def", "ault"]
b.arr; // ["def", "ault"]
c.arr; // ["def", "ault"]
然后我们改变b
。
b.updateVal();
其余不变,b更新了。
b.arr; // ["up", "da", "ted"]
然后您在 copyVal
函数中将相同的 b.arr
引用分配给 c.arr
。
this[prop] = _alls[oName][prop]; // Copy the reference.
您的最终更改会创建一个完整的新 数组并将其分配给b
。
b.arr=["over", "written"];
你得到了。
a.arr; // ["def", "ault"]
b.arr; // ["over", "written"] a new array you've created in the final step.
c.arr; // ["up", "da", "ted"] which is the old b array still being referenced.
关于javascript - 为什么这些数组按值传递而不是按引用传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53937158/