January 19, 2007

Converting the arguments object to an Array

The arguments object is an Array-like object providing access to arguments passed to a function. When hacking with functions, we frequently need to manipulate and pass around arguments as an Array. The Prototype library uses it's $A() function to accomplish the conversion, which is intuitive and beautiful.

Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}

Yet there is a another way.

//... inside a function definition
var args = [].slice.call(arguments);

// or var args = Array.prototype.slice.call(arguments);
//...

The slice(start, end) method of an Array object returns a copy of a specified portion of the array. Here we omit the start and end arguments and call slice() upon the arguments object. An array containing all arguments is returned. Then we can modify the array as we need and pass it to the apply() method of functions.


Notice that slice() only does a shallow copy and the return value is just an array any without magical behavior of the arguments object. There is no args.callee property. Moreover, if a parameter is listed at the nth position in the parameter list of the function definition, arguments[n] is a synonym for the local variable corresponding to the nth argument. Any change made to arguments[n] will affect the local variable because it's actually modifying the named property of the call object. However, since args is just a shallow copy of arguments, assigning args[n] will not affect the local variable. To demonstrate this,


function f (a) {
    alert('a: ' + a);
    var args = [].slice.call(arguments);
    arguments[0] = 'Assigning arguments[0] affects a';
    alert('a: ' + a);
    args[0] = 'Assigning args[0] does not change a';
    alert('a: ' + a);
}
f('JavaScript rocks!');


The three alerts will display "a: JavaScript rocks", "a: Assigning arguments[0] affects a" and "a: Assigning arguments[0] affects a" in order.


Tip: [].slice.call() can be used for any Array like objects, not only limited to the arguments object.

5 comments:

Gevorg Sargsyan said...

Very nice!

Actually this allows to play with arguments object as with an array, also using all other Array object methods (join, shift...).

Case with slice() method usage is just particular case of array copying, and is equal to case of using concat() method without arguments.

Anonymous said...

I'm the sort of guy who loves to taste hot stuff. Presently I am building my private pv panels. I'm managing it all alone without the aid of my men. I'm using the net as the only path to acheive that. I came across a truly awesome site that explains how to build solar panels and so on. The internet site explains all the steps required to solar panel construction.

I am not exactly sure bout how correct the info given there is. If some guys over here who have xp with these works can have a peak and give your feedback in the thread it would be grand and I'd extremely appreciate it, cauze I extremely would love to try [URL=http://solar-panel-construction.com]solar panel construction[/URL].

Tnx for reading this. You people rock.

Anonymous said...

Keep posting stuff like this i really like it

Anonymous said...

Nice fill someone in on and this enter helped me alot in my college assignement. Say thank you you seeking your information.

Anonymous said...

Well I to but I contemplate the list inform should have more info then it has.