Though perhaps less efficient considering that the concatenation now being done via the join() method is for only two elements of an array in each case, I think it demonstrates that no eval is required or used.
It does no such thing — at first glance it looks like the jQuery animate() function does something like this for each step:
Code:
window.curel = self;
for (var p in prop)
eval('curel.style.' + p + prop[p]);
As it turns out, I read through the jQuery animate() function and it seems in fact to use a regex to parse out the 'operator', which is presumably somewhat better than eval(), but I would still prefer a big operator lookup table, both for efficiency and flexibility.
Here's one:
Code:
var Operator = {
'+' : function(a, b) { return b === undefined ? +a : a + b; },
'-' : function(a, b) { return b === undefined ? -a : a - b; },
'/' : function(a, b) { return a / b; },
'*' : function(a, b) { return a * b; },
'%' : function(a, b) { return a % b; },
'>' : function(a, b) { return a > b; },
'<' : function(a, b) { return a < b; },
'>=' : function(a, b) { return a >= b; },
'<=' : function(a, b) { return a <= b; },
'==' : function(a, b) { return a == b; },
'!=' : function(a, b) { return a != b; },
'===' : function(a, b) { return a === b; },
'!==' : function(a, b) { return a !== b; },
'>>' : function(a, b) { return a >> b; },
'<<' : function(a, b) { return a << b; },
'>>>' : function(a, b) { return a >>> b; },
'&' : function(a, b) { return a & b; },
'|' : function(a, b) { return a | b; },
'^' : function(a, b) { return a ^ b; },
'&&' : function(a, b) { return a && b; },
'||' : function(a, b) { return a || b; },
'in' : function(a, b) { return a in b; },
'!' : function(a) { return !a; },
'~' : function(a) { return ~a; },
'void ' : function(a) { return void a; },
'typeof ' : function(a) { return typeof a; },
'instanceof' : function(a, b) { return a instanceof b; },
'.' : function(a, b) { return a[b]; },
'()' : function(f) { return f.call(this, Array.prototype.slice.call(arguments, 1)); }
};
The user code would go something like:
Code:
foo.animate({'marginLeft' : ['+', 5]});
and the jQuery code would look like:
Code:
jQuery.each(prop, function(name, val) {
var op = val[0],
args = val,
s = self.style;
args[0] = s[name];
if (typeof op !== 'function')
op = Operator[op];
s[name] = op.apply(self, args);
});
That way we could use any simple operator in string form, for brevity, or, if we liked, create a more complex function to use to combine the values, and pass that instead. Also, there's no regex, so it's fast!
Bookmarks