views:

50

answers:

3

I'm writing a Javascript function that would manipulate an array written on-the-fly and sent as a parameter.

The function is written as follows:

function returnJourney(animation,clean){
    var properties = {};
    // loads of other inane stuff
    for(i in animation[0]) properties[animation[0][i]] = animation[0].i;
    // heaps more inane stuff
}

The animation in question is a set of parameters for a jQuery animation. Typically it takes the format of ({key:value,key:value},speedAsInteger,modifierAsString).

So to kick off initial debugging I call it with:

returnJouney(({'foo':'bar'},3000),1);

And straight off the bat things are way off. As far as I see it this would have returnJourney acknowledge clean === 1, and animation being an array with an object as its first child and the number 3000 as its second.

Firebug tells me animation evaluates as the number 3000. What am I doing wrong?

+1  A: 
properties[animation[0][i]] = animation[0].i;

should be

properties[animation[0][i]] = animation[0][i];

.i is the property literally called 'i'. As that (probably) doesn't exist, you'll be assigning undefined to each property.

returnJouney(({'foo':'bar'},3000),1);

also makes little sense — do you mean an array?:

returnJourney([{'foo':'bar'},3000],1);

(there is no ‘tuple’ type in JavaScript.)

Also, use var i in rather than the (typo) in in. Forgetting var gives you an accidental global, with potentially annoying-to-debug side-effects.

bobince
Thanks Bob, just needed an array syntax refresher :)
Barney
A: 

It's treating ({'foo':'bar'},3000) as an expression using the comma operator, which returns the right operand as its result. Perhaps you meant [{'foo':'bar'},3000].

Ignacio Vazquez-Abrams
+1  A: 

There's no tuple type in JavaScript. All you have is either object {} or array []. Both of them can understand any mixture of types. So you can either pass your animation parameter as array ([{'foo':'bar'},3000]), which looks like exactly what you wanted. Or, as it usually done in JavaScript, use object instead:

returnJourney({props: {foo: "bar"}, speed: 3000}, 1);

function returnJourney(animation, clean) {
     var props = animation.props;
     var speed = animation.speed;
}

Note that object notation let you ignore things you don't want to pass and makes it very clear what value means what.

As for why your animation resolves as 3000, it is really simple, this is how , operator works. It returns the last thing in braces. So (10, 20, 30) would evaluate to 30, so will (f(1000), "hello", 30). Only last value matters, others just ignored (but run anyway, so any side effects will be there).

vava