全球不断改变价值.可能通过引用或范围问题传递?帮助!链接中的详细示例

Global keeps changing value. Possible passing by reference or scoping issue? HELP! Detailed example at link

本文关键字:帮助 链接 问题 范围 改变 引用      更新时间:2023-09-26

如何防止使用局部变量的函数更改全局变量的值?就像我通过引用传递值而没有这样做的意思一样。

https://github.com/upstageleft/Weird-javascript-problem

当源数据(闭包中矩阵数组中的元素值)复制到局部变量,然后修改局部变量值时,全局变量会不断变化。

无法让我了解正在发生的事情,但是问题在FF,Safari和Chrome中始终如一地呈现。

链接包括代码和变量值的动态显示,并带有要重复的按钮。应该足够了,但您可以随时查看源代码进行验证。

示例数据:

在下面的列表中,第一项反映了全局变量的值,该值由通过帮助程序函数从闭包中的矩阵数组复制的值填充。

第二个列表显示全局值在不应该更改时发生了更改。矩阵的指定单元格的值已复制到一个新变量,并且该变量已作,但该操作的结果以某种方式复制回全局变量和矩阵变量!

  • globVal初始值:1,1←(应为常数)
  • globVar 的作用域:[对象窗口]
  • myObj: { oSrc: "1,1", oX: 2 }

以前:

  • 全球价值[0] (全球): 1
  • 操作: newVal = myVal[0] * myObj.oX
  • myVal[0] (本地): 1
  • 新瓦尔(本地): 2
  • 地图(1,1) (闭合): 1,1

后:

  • 全球价值[0] (全球): 2
  • 操作: myVal[0] = newVal
  • 我的瓦尔[0] (本地): 2
  • 新瓦尔(本地): 2
  • 地图(1,1) (闭合): 2,1

下面是执行操作的代码,以及一个帮助程序函数,用于从矩阵和包含要在操作中应用的数据值的对象中提取值。

CODE BLOCK A
 1 |  function doStuff(){
 2 |     var myVal = mxGet( myObj.oSrc );
 3 |     var newVal = myVal[0] * myObj.oX;
 4 |     myVal[0] = newVal; // weirdness happens here!
 5 | }
 6 |  
 7 | function mxGet( xy ){
 8 |     var x_y = xy.split(',');
 9 |     return map.see( x_y[0], x_y[1] );
10 | }
11 |
12 | myObj = {
13 |     oSrc: '1,1',
14 |     oX: 2
15 | }

下面是初始化全局的 onload 函数和存储矩阵的闭包。

CODE BLOCK B
 1 | function init(){
 2 |     globVal = mxGet('1,1'); // global declared here
 3 |     that = this;
 4 |     doStuff();
 5 | }
 6 |  
 7 | map = (function(){
 8 |     myHiddenMatrix = [ [ [0,0], [0,1], [0,2] ],
 9 |                         [ [1,0], [1,1], [1,2] ],
10 |                        [ [2,0], [2,1], [2,2] ] ];
11 |     return {
12 |         pin: function( x, y, val ){ myHiddenMatrix[ x ][ y ] = val; },
13 |         see: function( x, y ){ return myHiddenMatrix[ x ][ y ]; }
14 |     }
15 | })();

这就是javascript(以及许多现代语言)的工作方式。对象(本质上)通过引用传递,无论您喜欢与否。

在此处查看更多内容:Javascript是否通过引用传递?

设置全局时,将其设置为以下行中mxGet('1,1')返回的对象的引用:

globVal = mxGet('1,1');

如果您希望它是一个新对象,那么您实际上必须将globVal设置为新创建的对象,例如新数组,例如:

var x = mxGet('1,1');
globVal = [ x[0], x[1] ];

这将使globVal保持不变。这是一个微妙但重要的区别。