admin管理员组

文章数量:1344238

I created a 2D array that contains an object, and each object has two variables.

When I printed out those objects, I found that every object has the same value.

If I change one of the objects, other objects will change too.

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();
    }
}

I created a 2D array that contains an object, and each object has two variables.

When I printed out those objects, I found that every object has the same value.

If I change one of the objects, other objects will change too.

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();
    }
}

It just prints nine 2 2. I have no idea what's going on.

Even if I tried:

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

It prints nine 2 3.

I will be appreciated if anyone helps me.

:P

Share Improve this question edited Mar 27, 2019 at 12:39 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Mar 27, 2019 at 12:37 Ben_TWBen_TW 1156 bronze badges 1
  • 7 I'm pretty sure you want self.x to be this.x, etc. unless this is really a Python question. – Mark Commented Mar 27, 2019 at 12:41
Add a ment  | 

4 Answers 4

Reset to default 10

JavaScript is not Python, use this, and it will work.

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();
    }
}

(You luckily/unluckily ended up using Window.self, everywhere)

The assignment of x and y to self in the constructor is your problem, change self to this to point to the current instance of the class object.

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();
    }
}

From the MDN docs:

The Window.self read-only property returns the window itself, as a WindowProxy. It can be used with dot notation on a window object (that is, window.self) or standalone (self)

So in your case when you assigned x and y to self.x and self.y two new properties of the self was created and you kept overwriting them in your loop which resulted in the last value (2,2) of the iteration being assigned to the x and y property of self

The variable self you use is actually the window object, so self.x = x just attaches an x property to window and sets the value. When you call console.log(self.x, self.y); this gets the x and y properties from window and since there is only a single instance of that, you get the last assigned values.

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);

You want to use this to refer to the current object instance

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();
    }
}

The self doesnot refer to the instance of class. self in another name for window. See the snippet what is self

According to MDN

The Window.self read-only property returns the window itself

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

So every time you create a new instance of test self.x and self.y is change. self.y and self.x is same a window.x and window.y

Using this in place of self will solve the problem.

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();
    }
}

本文标签: Javascript each element of a array of objects having same valueStack Overflow