Assigning to arguments indicies will only change the associated argument value (let's call it the n-th argument) if the function was called with at least n arguments. The arguments object's numeric-indexed properties are essentially setters (and getters):
http://es5.github.io/#x10.6
Italics in the below are my comments on how the process relates to the question:
(Let) args (be) the actual arguments passed to the [[Call]] internal method
- Let - lenbe the number of elements in args.
 
- Let - indx=- len - 1.
 
- Repeat while - indx >= 0, (so, the below loop will not run when no arguments are passed to the function:)
 
(assign to the arguments object being created, here called map:)
- 
- Add nameas an element of the listmappedNames.
 
- 
- Let gbe the result of calling theMakeArgGetterabstract operation with argumentsnameandenv.
 
- 
- Let pbe the result of calling theMakeArgSetterabstract operation with argumentsnameandenv.
 
- 
- Call the [[DefineOwnProperty]] internal method of mappassing ToString(indx), the Property Descriptor {[[Set]]:p, [[Get]]:g, [[Configurable]]:true}, andfalseas arguments.
 
So, if the function is invoked with no arguments, there will not be a setter on arguments[0], so reassigning it won't change the parameter at index 0.
The same sort of thing occurs for other indicies as well - if you invoke a function with 1 parameter, but the function accepts two parameters, assigning to arguments[1] will not change the second parameter, because arguments[1] does not have a setter:
function fn(a, b) {
  arguments[1] = 'bar';
  console.log(b);
}
fn('foo');
 
 
So
a() and a(undefined) are the same thing right?
is not the case, because the second results in an arguments object with a setter and a getter on index 0, while the first doesn't.
Note that this odd interaction between the arguments and the function parameters is only present in sloppy mode. In strict mode, changes to arguments won't have any effect on the value an individual argument identifier contains:
'use strict';
function a(b) {
  arguments[0] = 2;
  return b;
}
console.log(a(1)); //returns 1