1

I'm having difficulties understanding behavior of Javascript.

Code:

function getPosition(element){
    var position = {
        x:$(".line div").has(element).index(),
        y:$(".line").has(element).index()
    };
    console.log(position.y);
    console.log(position)
    return position;
}

Now while calling it from function I'm getting results like this:

0

Object
x: 8
y: 3

What I don't understand is how is it possible to change object attributes when trying to access it via object reference, but not directly.

But when I call same function from console I get this:

0

Object
x: 8
y: 0

This is the same element passed to function. And it seems that it fails always when X or Y is 0(zero), when it's another number it's ok.

Could anyone explain what I'm doing wrong? Or is it somekind of JS bug? O_o

EDIT:

So I finally found out what the problem was. I always thought that I was passing values but unfortunately I was wrong all the time. During some searches on stackoverflow, I found topic about JS values and references.

If anyone is interested and too lazy to read the topic, you can look at this example. It's pretty much self explanatory.

function test(){
    var a = 5;
    var b = a; //b now has value of 5
    console.log("a:"+a+":b:"+b);
    b = 4;//a still has value of 5 and b is assinged to 4
    console.log("a:"+a+":b:"+b);
    var c = {val:1};
    var d = c; //d now has reference to c
    d.val = 2; //c.val changes because it is a reference
    console.log(c);
}

EDIT2: oh and by the way, how can I mark my question as answered?

Community
  • 1
  • 1
Vytautas Butkus
  • 5,365
  • 6
  • 30
  • 45

2 Answers2

3

console.log delays converting values to string until the application slows down so that logging doesn't slow down the application unnecessarily.

If the console.log(position) is showing a value that is different from that at the time console.log was called its because the position has been modified between the call and the time the console widget decided to format the value for display.

You can see this by trying the following HTML:

<script>
// Emits the JSON form when converted to a string.
var obj = {
  x: 1,
  toString: function () {
    return JSON.stringify(this);
  }
};

console.log(obj);  // Often {x:2}
console.log("" + obj);  // Reliably {x:1}  

obj.x = 2;
</script>

Look for code that does something like

obj = getPosition(...);
...
obj.y = <expression that evaluates to zero>

Alternatively, you can force eager formatting by changing

 console.log(position)

to

 console.log("" + position)
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • Ok, so now I know why is it possible to see two different values, but I cant find what I'm doing wrong in my code. I even change the names so that it doesn't overlap or something. How do I find out where's the problem? – Vytautas Butkus Mar 12 '12 at 20:15
  • @VytautusButkus, if you have Firefox handy, you can probably use [`Object.watch`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch) to install a property breakpoint on the `y` property of obj so you can dump `console.trace()` or `throw` when code modifies it. – Mike Samuel Mar 12 '12 at 20:42
  • Strange behaviour, if i set watch for object it get correct value, but as soon as I comment it out it comes back to wrong value. Any other tips? – Vytautas Butkus Mar 12 '12 at 22:13
  • Look at this:Object { x=8, y=0} and when I click on it http://i39.tinypic.com/972v7n.png for some reason it shows 0 in console, but when I open it in DOM it's 3 – Vytautas Butkus Mar 12 '12 at 22:20
  • @VytautasButkus, your watcher might be vetoing changes. – Mike Samuel Mar 12 '12 at 22:26
  • Ok, even if it's vetoing it doesnt matter, but how would anyone explain different values in DOM and in JSON itself? – Vytautas Butkus Mar 12 '12 at 22:42
0

So I finally found out what the problem was. I always thought that I was passing values but unfortunately I was wrong all the time. During some searches on stackoverflow, I found topic about JS values and references.

If anyone is interested and too lazy to read the topic, you can look at this example. It's pretty much self explanatory.

function test(){
    var a = 5;
    var b = a; //b now has value of 5
    console.log("a:"+a+":b:"+b);
    b = 4;//a still has value of 5 and b is assinged to 4
    console.log("a:"+a+":b:"+b);
    var c = {val:1};
    var d = c; //d now has reference to c
    d.val = 2; //c.val changes because it is a reference
    console.log(c);
}
Vytautas Butkus
  • 5,365
  • 6
  • 30
  • 45