0

Here's the repo: https://github.com/ZorvyY/projectiles

I've implement a Vector class and a projectile class(which is functionally just a pair of vectors). When I try to store a projectile object I've created in an array, the values of the projectile change. Here is the relevant code.

In src/Vec.js:

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

  // More methods...
}

In src/Projectile.js:

import Vec from './Vec.js';

class Projectile {
  constructor(position, velocity) {
    this.position = position;
    this.velocity = velocity;
  }

  // More methods...
}

In src/app.js:

import Projectile from './Projectile.js';
import Vec from './Vec.js';

let projectiles = [];

let canvas = document.getElementById('canvas');

function handleMouseDown(event) {
  let startX = event.offsetX;
  let startY = event.offsetY;

  function handleMouseUp(event) {
    let endX = event.offsetX;
    let endY = event.offsetY;

    let newProj = computeProjectile(startX, startY, endX, endY);
    console.log('newProj', newProj);
    canvas.removeEventListener('mouseup', handleMouseUp);
    //projectiles.push(newProj);
    //console.log(projectiles);
  }

  canvas.addEventListener('mouseup', handleMouseUp);
}

canvas.addEventListener('mousedown', handleMouseDown);

function computeProjectile (x1, y1, x2, y2) {
  console.log('In computeProjectile:');
  console.log(arguments);

  let startVec = new Vec(x1, y1);
  let endVec = new Vec(x2, y2);
  let deltaVec = Vec.minus(endVec, startVec);
  let proj = new Projectile(startVec, deltaVec);

  console.log('startVec', startVec);
  console.log('endVec', endVec);
  console.log('proj', proj);

  return proj;
}

In the current state, each console.log statement produces the expected values. However, when I uncomment the line projectiles.push(newProj);, the projectile object stores nonsensical values instead of properly computed values. Keep in mind that the console.log statements are executed before projectiles.push(newProj).

In other words:

function handleMouseDown(event) {
  let startX = event.offsetX;
  let startY = event.offsetY;

  function handleMouseUp(event) {
    let endX = event.offsetX;
    let endY = event.offsetY;

    let newProj = computeProjectile(startX, startY, endX, endY);
    console.log('newProj', newProj); //Nonsensical value if projectiles.push(newProj) is uncommented
    canvas.removeEventListener('mouseup', handleMouseUp);
    //projectiles.push(newProj);
    //console.log(projectiles);
  }

  canvas.addEventListener('mouseup', handleMouseUp);
}

canvas.addEventListener('mousedown', handleMouseDown);

function computeProjectile (x1, y1, x2, y2) {
  console.log('In computeProjectile:');
  console.log(arguments);

  let startVec = new Vec(x1, y1);
  let endVec = new Vec(x2, y2);
  let deltaVec = Vec.minus(endVec, startVec);
  let proj = new Projectile(startVec, deltaVec);

  console.log('startVec', startVec); //Always produces expected value
  console.log('endVec', endVec); //Always produces expected value
  console.log('proj', proj); //Will produce a different nonsensical value than newProj if projectiles.push(newProj) is uncommented

  return proj;
}

even if I replace the line let newProj = computeProjectile(startX, startY, endX, endY); with other constants (ie computeProjectile(12,10,50,50), the output of the console.log statements is different each time.

Here's an example output

Why would storing an object in an array AFTER outputting its values change what values were outputted?

  • 1
    You have code [here in the `animate()` function](https://github.com/ZorvyY/projectiles/blob/master/src/app.js#L22) in your repository that is modifying the items in the `projectiles` array. So, if you put things into the array, they will get modified by that code. – jfriend00 May 12 '18 at 16:44
  • What @jfriend00 is asking is crucial. Objects are displayed in the console are *lazily*, so if you `console.log` an object, then change it, then expand the values in the console, you'll see the changed values – VLAZ May 12 '18 at 16:45
  • As @vlaz says, `console.log()` is a bit lazy (it doesn't make copies of objects and does not immediately output) so if the objects are getting changed fairly soon, `console.log()` may output the future value, not the current value. If you want to output something immediately without the laziness, you can do `console.log(JSON.stringify(projectiles));` since `JSON.stringify()` immediately copies values into a string form at the moment you call it. – jfriend00 May 12 '18 at 16:46
  • That seemed to be the issue. When commenting out animate, the values were stored correctly. I wasn't aware that console.log was lazy. – Zoravur Singh May 12 '18 at 16:51

0 Answers0