this series as effective JavaScript 's reading notes.
arguments object is just an array-like object, but it does not have the methods provided by the array object, such as Shift , Push and so on. So calls such as:arguments.shift (),arguments.push () are wrong.
in the Item and the Item , you know that a function object exists on the Pager and the Apply method, then it is not possible to use them to make arguments You can also use the array method:
function Callmethod (obj, method) {var shift = [].shift;shift.call (arguments); Shift.call (arguments); return Obj[method] . apply (obj, arguments);}
However, the above method has problems in the following scenario:
var obj = {add:function (x, y) {return x + y;}}; Callmethod (obj, "add", +);//Error:cannot Read Property "Apply" of undefined
The error occurs because:
arguments object is not a copy of a function parameter. There is a referential relationship between the arguments of the function declaration and The arguments object that is saved. In the example above callmethod function, for example, two parameters of obj and methodare declared:
obj the reference is Arguments[0]
Method the reference is Arguments[1]
and in the call of two times shift.call (arguments) later, arguments by the original:
[obj, "add", page] Become a [+]
soobjthe reference fromobjitself into a -,Methodthe reference from"Add"Become a -. It's obvious .17[25]The result isundefined, because according toJavaScriptthe arithmetic rules, -will first be converted to Numberobject, and this object has no -this property.
The above example is to say that the arguments declared in the function and arguments is fragile, and the arguments for each claim are actually just arguments a reference to the corresponding position in the object.
It is important to note that the ES5 of the Strict Mode , the arguments to the function declaration do not refer to the arguments :
function Strict (x) {"Use strict"; arguments[0] = "Modified"; return x = = = Arguments[0];} function Nonstrict (x) {arguments[0] = "Modified"; return x = = = Arguments[0];} Strict ("unmodified"); Falsenonstrict ("unmodified"); True
just because in Strict and non- Strict mode, the parameters of the function declaration and arguments Inconsistent , so in order to avoid problems, do not modify arguments object is the safest thing to do.
If you do need to modify arguments object, you can first assign a value arguments object:
var args = [].slice.call (arguments);
when Slice method does not accept any arguments, the copy operation is performed and the resulting args is also a true array object. At the same time, There is no connection between args and the arguments of the function declaration, and it is safe to operate on it. Use this method to re-implement the callmethod function mentioned above:
function Callmethod (obj, method) {var args = [].slice.call (arguments, 2); return obj[method].apply (obj, args);} var obj = {add:function (x, y) {return x + y;}}; Callmethod (obj, "add", 17, 25); 42
Summarize:
- never modify arguments Object
- Use [].slice.call (arguments) Get arguments A copy of the object, and then modify the copy
Effective JavaScript Item 23 never modify arguments objects