0

I'm trying to port a PHP function I built to Javascript and have been finding many differences that cause a lot of extra work. I am stuck on this one and cannot find any logic to it:
X: 95.29
Y: 27.39
testParse2.RXdec : 0.1

 var curPos={};
 curPos={};
 console.log(curPos);       //X:97.19 Y:27.39 (I expect an empty object)
 console.log(curPos['X']);  //undefined (seems ok but makes no sense with above)
 console.log(curPos['Y']);  //undefined (seems ok but makes no sense with above)

   for(var Ri=0; Ri < 20; Ri++){    

     curPos['X'] = "";
     curPos['Y'] = "";
 console.log(curPos['X']);  // "" (seems ok)
 console.log(curPos['Y']);  // "" (seems ok)
 console.log(curPos);       //X:97.19 Y:27.39
     curPos.X = (((XY(lastPos[AV['A']], 'X')*1)+(testParse2.RXdec*1*Ri)).toFixed(10)*1);
     curPos.Y = (((XY(lastPos[AV['B']], 'Y')*1)+(testParse2.RYdec*1*Ri)).toFixed(10)*1);
 console.log(curPos);   // X:97.19 Y:27.39 (I expect X:95.29 + 0.1 each loop Y:27.39)
 console.log(curPos.X); // 95.29 (correct by why is above different?)
 console.log(curPos.Y); // 27.39 (correct by why is above different?)

}

The things that confuse me the most are:

  1. curPos gets a value before the loop even starts. The value is the value that curPos should have after the final iteration.

  2. during the loop the console log for curPos and curPos.X or .Y do not contain the same values.

  3. during the loop the console log for curPos is always the same despite changing .X and .Y each iteration

Edit: @str gave the correct explanation for the console trouble but it seems that this problem is beyond the console and actually effects the object values. after using JSON.strigify I can see this (which is good):

console.log(JSON.stringify(testParse2));
"Xdec":97.99
"Xdec":98.09
"Xdec":98.19

but now I try to transfer the data to its final array but that final array is filled with 'lazy' values:

T['tool'][T['curTool']]['points'][lineID] = testParse2;

console.log(JSON.stringify(T));
"Xdec":98.19,"Ydec":27.39,"curX":323.19,"curY":177.39
"Xdec":98.19,"Ydec":27.39,"curX":323.19,"curY":177.39
"Xdec":98.19,"Ydec":27.39,"curX":323.19,"curY":177.39

If I stop using objects in the loop and switch to variables then build my final array like this it works:

 T['tool'][T['curTool']]['points'][lineID] = {'curX' : curX,
                                              'curY' : curY,
                                              'TYP'  : 'DR',
                                              'lineID'   : lineID,
                                              'lineName' : lineName,};

How do you send the actual object values at a particular iteration of a loop to a different array?

mochaMame
  • 57
  • 9
  • 1
    In line #3, if `curPos` is not empty then there is something that you don't show us (and apparently don't see yourself). Given that code it will indeed be an empty object. Your line #2 is superfluous, you already do that in line #1. Check the value of `curPos` _before_ the `var` statement. Oh and use `JSON.stringify(curPos)` in the `console.log` statements to have the object's property values evaluated right then and there! – Mörre Feb 14 '18 at 08:52
  • ^^ That. If you just execute the first 5 lines of the code you've shown (in a fresh window) you'll get expected results. – Reinstate Monica Cellio Feb 14 '18 at 08:55
  • 2
    I recommend that you get familiar with the interactive JavaScript debugger in your browser, instead of relying only in `console.log()` statements. You can set a breakpoint on any line and see all of your variables and objects right then and there. And then you can single step through the code and see what happens each step of the way. This way you get immediate information about what your code actually does, instead of having to guess and which particular `console.log()` calls might be useful. – Michael Geary Feb 14 '18 at 08:57
  • You initialize an Object not an array. You can not get the value by curPos['X'], you have to convert it first to object. Beside that, you have some other issues, you are using again curPos={}; after the var which is not necessary. – AlexCode Feb 14 '18 at 08:58
  • 2
    To use the debugger, first move all your code inside a function and call that function. The reason for this is to let you see only your local variables without the clutter of the global namespace. Then put a `debugger;` statement at the top of your function; the code will stop there and you can single step through it after that. – Michael Geary Feb 14 '18 at 08:58
  • @paokg4 Not sure what you're referring to there, but it is perfectly normal to access a property of an object with code like `curPos['X']` - assuming that you have actually set such a property on the object. – Michael Geary Feb 14 '18 at 09:00
  • @paokg4 I think you are confusing [object property accessors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors) with [array accessors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). – str Feb 14 '18 at 09:01
  • As another note, dot notation such as `curPos.X` means exactly the same thing as bracket notation when the key is a constant string such as `curPos['X']`. The dot notation is simpler and cleaner in this case, but both forms refer to the very same property. – Michael Geary Feb 14 '18 at 09:01
  • @Mörre before the var statement curPos is also undefined. I did a search of my code and its not written anywhere. Many of the lines are superfluous because I was trying various ways to clear the object. – mochaMame Feb 14 '18 at 09:03
  • @MichaelGeary He didn't initialized any object properties, he has an empty object. – AlexCode Feb 14 '18 at 09:04
  • @str Yep agree. And for what it's worth I suggest to use an array [] from the begging not an object {}, you will probably later need to handle it as an array. – AlexCode Feb 14 '18 at 09:07
  • @Nama Having said all that, are you _sure_ that the very first `console.log()` call displays the `X` and `Y` values mentioned in the comment on that line? Based on the code you posted, this is impossible, because you just initialized `curPos` to an empty object. There must be more to the code that you haven't shown here. – Michael Geary Feb 14 '18 at 09:07
  • @paokg4 I may be poor at javascript but I have read enough stackoverflow pages to know that and object can be accessed with [ ] even though you create it with { }. Besides it works everywhere else I do it. – mochaMame Feb 14 '18 at 09:07
  • @Nama yes, what I was meant its that you have an empty object, read above suggestions. – AlexCode Feb 14 '18 at 09:09
  • @MichaelGeary No, not necessarily. See my answer, that is a common mistake (but I did not find a good duplicate for it). – str Feb 14 '18 at 09:09
  • @str Excellent point, I'm familiar with the delayed evaluation but missed it when first reading the code. `JSON.stringify()` is a great way to make sure you're seeing the values at the time they were logged. This is also another reason why I recommend the interactive debugger, because it halts all JavaScript execution, so what you see are the actual values at the point where you stopped execution. – Michael Geary Feb 14 '18 at 09:13
  • @str is right. apparently the values in the console are not really the values in the object, I'm used to PHP not being 'lazy'. Not sure if I can solve my issues based on this but its a start at least. – mochaMame Feb 14 '18 at 09:23
  • @Nama To clarify what str is talking about, any value you see directly in the log is the actual value at the time you made the `console.log()` call. However, if you see an object in the log that is initially collapsed into a single line, and then you click the little triangle to display the full object, you're now seeing the current values at the moment you clicked. For efficiency, the developer tools don't save an entire object each time you log it. Does this make sense? Also, you should _really_ get in the habit of using the interactive single step debugger instead of `console.log()`. – Michael Geary Feb 14 '18 at 09:38
  • @MichaelGeary Thank you for the information on how to use the debugger, I wanted to use it before but didn't figure it out yet, your explanation makes it easy. After seeing information from you, str and the others I found another Question with more details. I might not like the way the console works but now that there is an explanation it wont drive me crazy. Thank you for your help. – mochaMame Feb 14 '18 at 23:43

1 Answers1

5

Browsers evaluate objects lazily in when logging. So when you expand them after the loop, they will show the properties they have at the moment of expanding and not the ones they had when the object was logged.

You can verify that by using

console.log(JSON.stringify(curPos));

instead of

console.log(curPos);
str
  • 42,689
  • 17
  • 109
  • 127
  • this is correct. I will try to get my code running again tomorrow now that I can see the correct console output. – mochaMame Feb 14 '18 at 09:25
  • https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays if anyone is looking in the future here is another question I found after getting the right keywords. It has very detailed answers regarding Javascripts console behavior in different browsers and possibility of webkit 'bugs'. – mochaMame Feb 14 '18 at 23:45
  • I updated my question. This problem is not limited to console input. Do you have any more insight? At the moment I changed from objects to plain variables and can get my program running. – mochaMame Feb 15 '18 at 02:07
  • @Nama Please add a *complete* example. What is `testParse2`, what is `T`? – str Feb 15 '18 at 07:47