JavaScript:如何遍历一个具有相同值的对象数组中的每个元素

3

我创建了一个包含对象的二维数组,每个对象都有两个变量。

当我打印出这些对象时,发现每个对象都具有相同的值。

如果我更改一个对象,其他对象也会改变。

class test{
    constructor(x, y){
        self.x = x;
        self.y = y;
    }
    print(){
        console.log(self.x, self.y);
    }
}

arr = new Array(3);

for(let i=0;i<3;i++){
    arr[i] = new Array(3);
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j] = new test(i, j);
    }
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j].print();
    }
}

它只打印九个2。 我不知道发生了什么。

即使我尝试:

arr[1][2] = new test(2, 3);

它输出九个数字 2 3。

如果有人帮助我,我将感激不尽。

:P


7
我很确定你希望self.x变成this.x,等等,除非这真的是一个Python问题。 - Mark
4个回答

10
JavaScript不是Python,使用this,它会生效。
class test{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    print(){
        console.log(this.x, this.y);
    }
}

arr = new Array(3);

for(let i=0;i<3;i++){
    arr[i] = new Array(3);
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j] = new test(i, j);
    }
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j].print();
    }
}

(你幸运/不幸地最终在各个地方使用了 Window.self


2
@Teemu,谢谢。这有点让我困扰,因为它应该是在抱怨访问“undefined”字段。 - tevemadar

5

构造函数中将 xy 分配给 self 是您的问题,将 self 改为 this ,以指向类对象的当前实例。

class test{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    print(){
        console.log(this.x, this.y);
    }
}

arr = new Array(3);

for(let i=0;i<3;i++){
    arr[i] = new Array(3);
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j] = new test(i, j);
    }
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j].print();
    }
}

根据MDN的文档, Window.self是一个只读属性,返回自身窗口对象作为WindowProxy。可以使用点符号在窗口对象上(即window.self)或独立地(self)使用。
所以,在您的情况下,当您将x和y分配给self.x和self.y时,将创建self的两个新属性,并在循环中不断重写它们,导致迭代的最后一个值(2,2)被分配给self的x和y属性。

4
你使用的变量 self 实际上是 window 对象,因此 self.x = x 只是将一个 x 属性附加到 window 并设置其值。当你调用 console.log(self.x, self.y); 时,它会从 window 获取 xy 属性,并且由于只有一个实例,你会得到最后分配的值。

class test{
    constructor(x, y){
        self.x = x;
        self.y = y;
    }
    print(){
        console.log(self.x, self.y);
    }
}

new test(4, 2);

console.log(window.x);
console.log(window.y);

您想使用this以引用当前对象实例

class test{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    print(){
        console.log(this.x, this.y);
    }
}

arr = new Array(3);

for(let i=0;i<3;i++){
    arr[i] = new Array(3);
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j] = new test(i, j);
    }
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j].print();
    }
}


天啊,我没有注意到。 - Ben_TW
非常感谢您。 - Ben_TW
1
@Ben_TW 没关系,我们都会犯错误并从中学习。我知道关于“self”的原因是因为我过去曾经犯过类似你的错误。解决它也花了我一些时间 :P - VLAZ

2

self并不是指代class实例本身的关键字,它其实是window的另一种称呼。请看下面的代码片段,了解self的含义:

根据MDN的说明:

Window.self只读属性返回窗口本身

class test{
    constructor(x, y){
        console.log(self === window) //true
        console.log(self) //widnow object       
    }
}
let x = new test(1,2);

每次创建test的新实例时,self.xself.y都会改变。 self.yself.xwindow.xwindow.y相同。
使用this代替self可以解决这个问题。

class test{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    print(){
        console.log(this.x, this.y);
    }
}

arr = new Array(3);

for(let i=0;i<3;i++){
    arr[i] = new Array(3);
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j] = new test(i, j);
    }
}

for(let i=0;i<3;i++){
    for(let j=0;j<3;j++){
        arr[i][j].print();
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接