JavaScript 循环正在更改数据源数组以及结果 - 为什么会这样?

发布于 2024-10-24 22:19:57 字数 606 浏览 2 评论 0原文

我完全困惑了。我有一个对象,其中包含全局“散列”数字数组(在 objectA 中),该对象在将数字组合成新系列(在 objectB 中)的循环中引用。

var objectB = objectA[arrActive[0]]; 
for (i=1; i<arrActive.length; i++) {    
    var _this = arrActive[i];
    for (x=0; x<objectB.length; x++) {  
    objectB[x][1] += objectA[_this][x][1];  
    }
}

奇怪的是,源数组 objectA 中的值在循环期间递增 - 但为什么呢?据我所知,我只是从 objectA 读取数据以写入 objectB!

这令人沮丧,因为每次调用该函数时,数字都会进一步膨胀!

JSFiddle 的工作示例在这里: http://jsfiddle.net/ZbWGH/ - 我完全误解了 + = 运算符?我确信这是一个很容易理解的问题。

预先感谢您的任何帮助!

I am completely perplexed. I have an object containing a global "hashed" array of numbers (in objectA) that is referred in a loop that combines the numbers into a new series (in objectB).

var objectB = objectA[arrActive[0]]; 
for (i=1; i<arrActive.length; i++) {    
    var _this = arrActive[i];
    for (x=0; x<objectB.length; x++) {  
    objectB[x][1] += objectA[_this][x][1];  
    }
}

What's weird is that the values in objectA, the source array, are being incremented during the loop - but why? As far as I'm aware, I'm just reading from objectA to write to objectB!

This is frustrating because every time the function is called, the numbers are further inflated!

Working example on JSFiddle is here: http://jsfiddle.net/ZbWGH/ - have I completely misunderstood the += operator? I'm sure this is a simple issue to understand.

Thanks in advance for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掩饰不了的爱 2024-10-31 22:19:57

您将对实例 objectA['ONE'] 的引用放入名为 objectB 的变量中 - 该变量中的任何更改确实都会更改实际值。

相反,您可能有兴趣将数组克隆或“干净复制”到objectB中,这样就不会更改原始数组。

执行此操作的简单函数是:

function CopyArray(arr) {
    var clone = [];
    for (var i = 0; i < arr.length; i++) {
        var subArray = [];
        for (var j = 0; j < arr[i].length; j++)
            subArray.push(arr[i][j]);
        clone.push(subArray);
    }
    return clone;
}

并使用它:

var objectB = CopyArray(objectA[arrActive[0]]); 

更新了 jsFiddle: http://jsfiddle.net/ yahavbr/ZbWGH/1/

You're putting reference to the instance objectA['ONE'] in variable called objectB - any change in that variable will indeed change the actual value.

Instead you might be interested in getting clone or "clean copy" of the array into objectB and this way it won't change the original array.

Simple function that will do this is:

function CopyArray(arr) {
    var clone = [];
    for (var i = 0; i < arr.length; i++) {
        var subArray = [];
        for (var j = 0; j < arr[i].length; j++)
            subArray.push(arr[i][j]);
        clone.push(subArray);
    }
    return clone;
}

And to use it:

var objectB = CopyArray(objectA[arrActive[0]]); 

Updated jsFiddle: http://jsfiddle.net/yahavbr/ZbWGH/1/

野生奥特曼 2024-10-31 22:19:57

此外,A += B 类似于 A = A + B,因此您修改了 objectA。

Further more A += B is like A = A + B, so you modify objectA.

陌生 2024-10-31 22:19:57

你认识C吗? C 中的引用/指针是理解 Javascript 中复杂变量的好方法。 “Komplex”表示除数字、字符串、布尔值之外的所有内容 - 其他所有内容都是“对象”。复杂类型(对象)的变量确实像指针。如果您知道“按引用调用”和“按值调用”的概念,那么在 Javascript 中两者都不是:如果将对象赋予函数,则“指针”本身是按值调用,但该值是对对象(实际上是堆上存储对象的区域,尽管 JS 程序员不像 C/C++ 那样处理堆,但它仍然是存储内容的地方)。示例:

function fn (a) {
  //changing the argument itself does NOT change the original object
  a = null;
  //but changing its properties does:
  a.foo = 42;
}

var o = { foo:1, bar:2 };

fn(o);

现在应该清楚为什么如果您想要真正的“按值调用”,则必须克隆对象。 JS 选择这种实现是因为,否则每次使用非原始类型调用函数时,都必须复制堆,而 99% 的情况下这是不必要的。函数式编程的“真正”精神当然是纯粹的按值调用,在这里我们看到实际生活(性能和内存使用)的考虑侵入了理论:)

Do you know C? References/pointers in C are a good way to understand komplex variables in Javascript. "Komplex" meaning everything that is not Number, String, Boolean - everything else is "Object". Variables for the komplex types (Objects) are indeed like pointers. If you know the concepts of "call by reference" and "call by value", in Javascript it's neither, sort of: If you give objects to functions the "pointer" itself is call by value, but the value is a reference to the object (really to the area on the heap where the object is stored, even though JS programmers don't handle heap like in C/C++ it still is where stuff is stored). Example:

function fn (a) {
  //changing the argument itself does NOT change the original object
  a = null;
  //but changing its properties does:
  a.foo = 42;
}

var o = { foo:1, bar:2 };

fn(o);

So now it should become clear why you have to clone an object if you want real "call by value". This implementation was chosen for JS because otherwise every single time a function is called with a non-primitive type the heap would have to be copied over, and 99% of the time that just is not necessary. The "true" spirit of functional programming would of course be pure call by value, here we see practical life (performance and memory usage) considerations intruding upon theory :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文