# 理解函数调用 🔥

# 隐式函数参数

除了在函数定义中显式声明的参数之外,函数调用时还会传递两个隐式的参数:arguments和this,并且可以在函数内正常访问。

# arguments参数

arguments参数是传递给函数的所有参数集合。无论是否有明确定义对应的形参,通过它我们都可以访问到函数的所有参数。借此可以实现原生JavaScript并不支持的函数重载特性,而且可以实现接收参数数量可变的可变函数。其实,借助剩余参数(restparameter),对arguments参数的需求已经大大减少了。

arguments对象有一个名为length的属性,表示实参的确切个数。通过数组索引的方式可以获取单个参数的值。但是arguments对象仅是一个类数组的结构避免把它参数当作数组使用,尝试使用数组的方法时会报错!剩余参数是真正的Array实例

实现一个求和函数,来计算任意数量参数的和:

function sum(){
    let sum = 0
    for(let i = 0; i < arguments.length; i++){
        sum += arguments[i]
    }
    return sum
}

sum(1,2,3)
sum(2,3,4,5)

**arguments对象可以与剩余参数、默认参数和解构赋值参数结合使用注意**

严格模式下,剩余参数、默认参数和解构赋值参数的存在不会改变 arguments对象的行为,但是在非严格模式下就有所不同了

非严格模式中的函数没有包含剩余参数、默认参数和解构赋值,那么arguments对象中的值会跟踪参数的值(反之亦然)

function func(a) { 
  arguments[0] = 99;   // 更新了arguments[0] 同样更新了a
  console.log(a);
}
func(10); // 99
function func(a) { 
  a = 99;              // 更新了a 同样更新了arguments[0] 
  console.log(arguments[0]);
}
func(10); // 99

非严格模式中的函数有包含剩余参数、默认参数和解构赋值,那么arguments对象中的值不会跟踪参数的值(反之亦然)。相反, arguments反映了调用时提供的参数:

function func(a = 55) { 
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
func(10); // 10
function func(a = 55) { 
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
func(10); // 10
function func(a = 55) { 
  console.log(arguments[0]);
}
func(); // undefined

# this—函数上下文

函数的调用方式对函数内代码的执行有很大的影响,主要体现在this参数以及函数上下文是如何建立的。