前言
在函数调用时,arguments和this会被静默的传递给函数,并可以在函数体内引用它们,借以访问函数相关的一些信息。
其中arguments是一个类数组结构,它保存了调用时传递给函数的所有实参;this是函数执行时的上下文对象, 这个对象有些让人感到困惑的行为。 下面分别对他们进行讨论。
1. arguments
1.1 背景
JavaScript 允许函数在调用时传入的实参个数和函数定义时的形参个数不一致, 比如函数在定义时声明了 n 个参数, 在调用函数时不一定非要传入 n 个参数,例如:
// 1. 定义有一个形参的函数fn()function fn(arg){}// 2. 在调用时传入 0 个或 多个参数,并不会报错fn(); // 传入 0 个参数fn(1,'a',3); // 传入多个参数
1.2 arguments 与 形参的对应关系
arguments是个类数组结构,它存储了函数在调用时传入的所有实参, 通过访问它的length属性可以得到其中保存的实参的个数,并可以通过arguments[n]按顺序取出传入的每个参数(n=1,2,..,arguments.length-1)。
参数在arguments中保存的顺序和传入的顺序相同, 同时也和形参声明的顺序相同,例如:
function fn(arg1, arg2, arg3){console.log(arg1 === arguments[0]); // trueconsole.log(arg2 === arguments[1]); // trueconsole.log(arg3 === arguments[2]); // true}fn(1,2,3); // 调用
当传入的实参多于形参个数时,想要获得多余出的实参,就可以用arguments[n]来获取了, 例如:
// 定义只有一个形参的函数function fn(arg1){ console.log('length of arguments is:',arguments.length);console.log('arguments[0] is:', arguments[0]); // 获取传入的第一个实参, 也就是形参 arg1 的值console.log('arguments[1] is:', arguments[1]); // 获取第二个实参的值, 没有形参与其对应console.log('arguments[2] is:', arguments[2]); // 获取第二个实参的值, 没有形参与其对应}fn(1,2,3); // 传入 3 个实参// 可以得到实际上传入的实参的个数并取出所有实参// length of arguments is: 3// arguments[0] is: 1// arguments[1] is: 2// arguments[2] is: 3
1.3 arguments 与 形参的值相互对应
在非严格模式下, 修改arguments中的元素值会修改对应的形参值;同样的,修改形参的值也会修改对应的arguments中保存的值。下面的实验可以说明:
function fn(arg1, arg2){// 1. 修改arguments元素,对应的形参也会被修改arguments[0] = '修改了arguments';console.log(arg1); // 2. 修改形参值,对应的arguments也会被修改arg2 = '修改了形参值';console.log(arguments[1]); }fn(1,2);// '修改了arguments'// '修改了形参值'
但是,在严格模式下不存在这种情况, 严格模式下的arguments和形参的值之间失去了对应的关系:
新闻热点
疑难解答
图片精选