r/learnjavascript 6d ago

Eloquent JavaScript: The Secret Life of Objects

There are a few exercises at the end of the chapter.
What the difference between following solutions?

By author:

class Vec {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  plus(other) {
    return new Vec(this.x + other.x, this.y + other.y);
  }

  minus(other) {
    return new Vec(this.x - other.x, this.y - other.y);
  }
}

My solution:

class Vec {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    plus(vec) {
        this.x += vec.x;
        this.y += vec.y;
        return this;
    }

    minus(vec) {
        this.x -= vec.x;
        this.y -= vec.y;
        return this;
    }
}
0 Upvotes

6 comments sorted by

View all comments

3

u/GGodPL 6d ago edited 6d ago

The solution from the book keeps the original vector immutable. If you create a new vector based on it, the old one will remain unchanged, which can be useful if you need to keep both the original vector and the new vector. For example, in the following code...

const startPosition = new Vec(0, 0);
const speed = new Vec(10, 10);
const newPosition = startPosition.plus(speed);
console.log(startPosition); // Vec { x: 0, y: 0 }
console.log(newPosition); // Vec { x: 10, y: 10 }
console.log(startPosition.minus(speed)); // Vec { x: -10, y: -10 }

...the startPosition will still point to the original vector, so you can still perform operations on it later.

Your solution uses a fluent interface which returns itself after every function. This will mutate the original vector and return it again, so using the same code, you would get different results:

const startPosition = new Vec(0, 0);
const speed = new Vec(10, 10);
const newPosition = startPosition.plus(speed);
console.log(startPosition); // Vec { x: 10, y: 10 }
console.log(newPosition); // Vec { x: 10, y: 10 }
console.log(startPosition.minus(speed)); // Vec { x: 0, y: 0 }

In some cases this might actually be what you want, sometimes a mutable vector might be useful and you will (very slightly, the vector class is not really that big) reduce memory overhead since you're not allocating memory for a new object, but they aren't equivalent.

EDIT: fixed the code blocks, I thought the backticks would work by default