js小知识-函数参数与arguments对象的区别

529 阅读2分钟

写在前面

今天无意中看到一个js的面试题。考的是函数的形参与arguments的对应关系。 在此做一个记录。

题目再现

看看下面代码打印的结果是什么

function course(name, age) {
    console.log(name);
    console.log(arguments[1]);
    arguments[1] = 2;
    console.log(age);
    console.log(arguments[1]);
}
course('哈哈哈');

这道题的答案先放着等会回来再看。先将两个比较简单的题目。

看题目之前你要知道什么是arguments,你可以把它理解为函数实参对象,它的官方解释是一个对应于函数传递参数的类数组对象。重要的事情说三遍是对象!对象!对象!不是数组

还不明白就去看看官方文档:developer.mozilla.org/zh-CN/docs/…

知识讲解

非严格模式和严格模式有着不同的关系,我们分开来看。

非严格模式

  • 例1
function a(x) {
    x =2;
    console.log(arguments[0]); 
    console.log(x);
}
a()

第一个的结果是undefined,第二个是2

  • 例2
function a(x) {
    arguments[0] = 1;
    console.log(x, arguments[0]);
}
a();

第一个的结果是undefined,第二个结果是1.

  • 例3
function a3(x) {
    x = 2;
    console.log(x, arguments[0]);
}
a3(2);   //2  2
<hr------------------------------------------>
function a4(x) {
    arguments[0] = 1;
    console.log(x, arguments[0]);
}
a(1);   //1  1

规律

如果缺少参数,实参与形参不是一一对应,那么arguments对象和实参就是无关的;如果实参形参一一对应,那么arguments和参数就是双向绑定的,改变一个另外一个也随之改变。

严格模式

我们来看严格模式,直接看代码

function b1(x) {
    'use strict'
    x = 2;
    console.log(x, arguments[0]);
}
b1(); //2 undefined

function b3(x) {
    'use strict'
    arguments[0] = 2;
    console.log(x, arguments[0]);
}
b3(0); // 0,2

我们可以arguments和参数不论是否一一对应,都是独立的。

开篇的题

function course(name, age) {
    console.log(name);
    console.log(arguments[1]);
    arguments[1] = 2;
    console.log(age);
    console.log(arguments[1]);
}
course('哈哈哈');

我们看这个题,首先它是在非严格模式下,实参只有一个,arguments.length==1,它与name是相关联,也就是arguments[0]与name绑定,arguments与age无关。

  • 所以第一个结果是哈哈哈
  • 第二个结果是undefined
  • 第三个结果是undefined
  • 第四个结果是2

这个题目解题的关键就是arguments什么时候和形参双向绑定,什么时候没有关系。

总结

参数是否完整下有坑,大家要分清,再看个简单的题,如果能分清那么就说明掌握啦

ending...