JS的arguments

1、前言

一、在函数调用的时候,浏览器每次都会传递进两个隐式参数:数组

一个是函数的上下文对象this,另外一个则是封装实参的类数组对象arguments浏览器

二、与其余程序设计语言不一样,ECMAScript不会验证传递给函数的参数个数是否等于函数定义的参数个数。开发者定义的函数均可以接受任意个数的参数(但根据Netscape的文档,最多可接受255个),而不会引起任何错误。任何遗漏的参数都会以undefined传递给函数,多余的函数将忽略。函数

即参数从左向右进行匹配,若是实参个数少于形参,后面的参数对应赋值为undefined。如:ui

function fn (a, b, c) {
    console.log(a, b, c); // 1 2 undefined
    // 函数对象的length属性就是函数形参的个数
    console.log(fn.length); // 3
}
fn(1, 2);
复制代码

2、arguments

一、描述

arguments的定义是对象,可是由于对象的属性是无序的,而arguments是用来存储实参的,是有顺序的,它具有和数组相同的访问性质及方式,并拥有数组长度属性length,因此arguments是特殊的对象,又叫类数组对象,当咱们听到类数组时就能够知道说的是argumentsthis

arguments是一个类数组对象,用来存储实际传递给函数的参数,使调用函数时不局限于函数声明所定义的参数列表。spa

function fn() {
    console.log(arguments);
    console.log(typeof arguments); // object
    console.log(toString.call(arguments)); // [object Arguments]
}
fn('name', 'age');
复制代码

二、访问实参和检查实参个数

arguments访问单个参数的方式与访问数组元素的方式相同。例如arguments[0]arguments[1]arguments[n],在函数中不须要明确指出参数名,就能访问它们。经过length属性能够知道实参的个数。prototype

function f2() {
    console.log(arguments[0]); // name
    console.log(arguments[1]); // age
    console.log(arguments.length); // 2
}
f2('name', 'age');
复制代码

三、callee属性

每个对象都有本身的属性,而arguments有一个callee属性,返回正被执行的Function对象。设计

function f3() {
    console.log(arguments.callee === f3); // true
}
f3('name', 'age');
复制代码

四、arguments的修改

在正常的模式下,arguments对象是容许在运行时进行修改的。3d

function f4() {
    arguments[0] = 'sex';
    console.log(arguments[0]); // sex
}
f4('name', 'age');
复制代码

五、转化成真实数组

arguments是类数组对象,除了length属性和索引元素以外没有任何Array属性。例如,它没有 pop方法。可是它能够被转换为一个真正的Array:code

function f5(){
    // 可使用slice来将arguments转换为真实数组
    var args1 = Array.prototype.slice.call(arguments);
    var args2 = [].slice.call(arguments);
    // 也可使用Array.from()方法或者扩展运算符来将arguments转换为真实数组
    var args3 = Array.from(arguments);
    var args4 = [...arguments];
}
f5('name', 'age');
复制代码

3、应用

一、借用arguments.length能够来查看实参和形参的个数是否一致

function fn (a, b, c) {
    if (fn.length != arguments.length) {
        console.log('形参和实参的个数不一致');
    } else{
        console.log('形参和实参的个数一致');
    }
}
fn(1, 2);
复制代码

二、借用arguments.callee来让匿名函数实现递归:

let sum = function (n) {
    if (n == 1) {
        return 1;
    } else {
        return n + arguments.callee(n - 1); // 5 4 3 2 1
    }
}
console.log(sum(6)); // 21
复制代码

三、遍历参数求和或者求最大值

function max () {
    var max = arguments[0];
    for (item of arguments) {
        if (item > max) {
            max = item;
        }
    }
    return max;
}
console.log(max(5, 3, 2, 9, 4)); // 9
复制代码

四、模拟函数重载

重载函数是函数的一种特殊状况,为方便使用,C++容许在同一范围中声明几个功能相似的同名函数,可是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不一样,也就是说用同一个函数完成不一样的功能。

arguments对象判断传递给函数的参数个数,便可模拟函数重载:

function doAdd() {
    if(arguments.length == 1) {
        console.log(arguments[0] + 5);
    } else if(arguments.length == 2) {
        console.log(arguments[0] + arguments[1]);
    }
}
doAdd(10);  // 15
doAdd(10, 20); // 30
复制代码

4、总结

一、arguments是一个类数组对象,用来存储实参;具备lengthcallee等属性;能够用arguments[0]这个形式访问实参;能够转换为真实数组。

二、arguments和函数相关联,其只有在函数执行时可用,不能显式建立。

三、arguments能够用来遍历参数;经过callee实现递归;也能够模拟函数重载。

相关文章
相关标签/搜索