全球不断变化的价值。可能通过引用或范围问题传递?帮助! link 处的详细示例
Global keeps changing value. Possible passing by reference or scoping issue? HELP! Detailed example at link
如何防止使用局部变量的函数改变全局变量的值?就好像我无意中通过引用传递了值。
https://github.com/upstageleft/Weird-javascript-problem
当源数据(闭包中矩阵数组中元素的值)被复制到局部变量,然后局部变量值被修改时,全局变量不断变化。
无法理解正在发生的事情,但问题在 FF、Safari 和 Chrome 中始终存在。
Link 包括代码和变量值的动态显示,并带有重复按钮。应该足够了,但您可以随时查看源代码进行验证。
示例数据:
在下面的列表中,第一项反映了全局变量的值,该值由通过辅助函数从闭包中的矩阵数组复制的值填充。
第二个列表显示全局值在不应该的时候发生了变化。矩阵指定单元格的值已被复制到一个新变量,并且该变量已被操作,但该操作的结果以某种方式被复制回全局变量和矩阵变量!
- globVal初始值:1,1 ←(应该是常量)
- globVar 的范围:[object Window]
- myObj: { oSrc: "1,1", oX: 2 }
之前:
- globVal[0](全局):1
- 运算:newVal = myVal[0] * myObj.oX
- myVal[0](本地):1
- newVal(本地):2
- map.see(1,1)(闭包):1,1
之后:
- globVal[0](全局):2
- 操作:myVal[0] = newVal
- myVal[0](本地):2
- newVal(本地):2
- map.see(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(以及许多现代语言)的工作方式。无论您喜欢与否,对象(本质上)都是通过引用传递的。
在此处查看更多内容:
Does Javascript pass by reference?
当您设置全局变量时,您将其设置为 mxGet('1,1')
在这一行中返回的对象的引用:
globVal = mxGet('1,1');
如果您希望它成为一个新对象,那么您实际上必须将 globVal
设置为一个新创建的对象,例如一个新数组,例如:
var x = mxGet('1,1');
globVal = [ x[0], x[1] ];
这将使 globVal
保持不变。这是一个微妙但重要的区别。
如何防止使用局部变量的函数改变全局变量的值?就好像我无意中通过引用传递了值。
https://github.com/upstageleft/Weird-javascript-problem
当源数据(闭包中矩阵数组中元素的值)被复制到局部变量,然后局部变量值被修改时,全局变量不断变化。
无法理解正在发生的事情,但问题在 FF、Safari 和 Chrome 中始终存在。
Link 包括代码和变量值的动态显示,并带有重复按钮。应该足够了,但您可以随时查看源代码进行验证。
示例数据:
在下面的列表中,第一项反映了全局变量的值,该值由通过辅助函数从闭包中的矩阵数组复制的值填充。
第二个列表显示全局值在不应该的时候发生了变化。矩阵指定单元格的值已被复制到一个新变量,并且该变量已被操作,但该操作的结果以某种方式被复制回全局变量和矩阵变量!
- globVal初始值:1,1 ←(应该是常量)
- globVar 的范围:[object Window]
- myObj: { oSrc: "1,1", oX: 2 }
之前:
- globVal[0](全局):1
- 运算:newVal = myVal[0] * myObj.oX
- myVal[0](本地):1
- newVal(本地):2
- map.see(1,1)(闭包):1,1
之后:
- globVal[0](全局):2
- 操作:myVal[0] = newVal
- myVal[0](本地):2
- newVal(本地):2
- map.see(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(以及许多现代语言)的工作方式。无论您喜欢与否,对象(本质上)都是通过引用传递的。
在此处查看更多内容: Does Javascript pass by reference?
当您设置全局变量时,您将其设置为 mxGet('1,1')
在这一行中返回的对象的引用:
globVal = mxGet('1,1');
如果您希望它成为一个新对象,那么您实际上必须将 globVal
设置为一个新创建的对象,例如一个新数组,例如:
var x = mxGet('1,1');
globVal = [ x[0], x[1] ];
这将使 globVal
保持不变。这是一个微妙但重要的区别。