前言

  JavaScript 函数参数不同于其他编程语言,既不需要规定参数的类型,也不需要关心参数的个数,因此 JavaScript 因函数参数而变得十分灵活,本文总结一下 arguments 参数对象的相关知识点。

正文

  1、arguments参数对象是什么

  JavaScript 中函数既不需要关心传入的参数个数,也不需要关心这些参数的数据类型。正因为这一特性,JS函数没有重载。因此定义函数的时要接收两个参数,并不意味着就要传入两个参数,你可以传入一个、三个,甚至一个也不传,编译器都不会报错。arguments对象是一个类数组对象(但是不是Array 的实例),因此可以使用括号语法来访问其中的元素,要确定元素的个数,可以访问 arguments.length 属性。

    function foo() {
console.log(arguments);
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
foo(1, 2, 3, "a")
// 0: 1
// 1: 2
// 2: 3
// 3: "a"
// callee: ƒ foo()
// length: 4
// Symbol(Symbol.iterator): ƒ values()
// [[Prototype]]: Object
// 1 2 3 "a"

  ECMAScript 函数的参数只是为了方便才写出来的,并不是必须写出来的,可用通过arguments[0]...访问, arguments 对象可以跟命名参数一起使用。

    foo(1, 2, 3, "a")
function foo(name, age) {
console.log(name, arguments[1])
}
foo(1,2) // 1 2

  2、参数默认值

  JS 中函数可以接收任意数量的参数,而无视函数声明处的参数数量,但是有时候需要为传递参数设置默认值。在ES6 之前,我们的代码如下设置默认值:
       function getValue(value){
value = value || 100
return value
}
console.log(getValue())//100这里使用了默认值100
console.log(getValue(0))//100 这里入参为0的时候

  在ES6之后提供了非常方便的设置默认值方法:

        function getValue(value = 100) {
return value;
}
console.log(getValue()); //100
console.log(getValue(0)); //0
console.log(getValue(null)); //null null默认值是有效的

  3、参数传递和接收

  这里主要写一下ES6 之后常用的参数传递的快捷方法,先来看下面代码:

        function getSum() {
var sum = 0
for (let i = 0; i < arguments.length; ++i) {
sum += arguments[i];
}
return sum; }
console.log(getSum(...[1, 2, 3])); // 6

  上面的代码中,getSum方法入参为一个数组,通过扩展运算符分别传入,这种写法比较常见。前面我们提到arguments对象为一个类数组对象,下面的代码中通过扩展运算符将类数组对象转为数组,如下:

       function getSum(...values) {
console.log(arguments);
console.log(values);
// 顺序累加 values 中的所有值
// 初始值的总和为 0
return values.reduce((x, y) => x + y, 0);
}
console.log(getSum(1, 2, 3)); // 6

  运行结果如下:

  4、函数作为参数和返回值

  因为函数名在 JS 中就是变量,所以函数可以用在任何可以使用变量的地方。这意味着不仅可以把函数作为参数传给另一个函数,而且还可以在一个函数中返回另一个函数。

        function creatSum(addSum, num) {
return addSum(num)
}
function addSum(num) {
return num + 10
}
var sum = creatSum(addSum, 1)
console.log(sum);//11

  5、箭头函数中参数问题

  箭头函数中没有 arguments 对象,但可以在包装函数中把它提供给箭头函数。

  箭头函数虽然不支持 arguments 对象,但支持收集参数的定义方式,因此也可以实现与使用 arguments 一样的逻辑。

    function foo() {
let bar = () => {
console.log(arguments[0]); // 5
};
bar();
}
foo(5);

  6、arguments.callee 使得函数逻辑和函数名解耦

  解决上面的问题可以首先来看一道题:通过一个函数求传入参数的阶乘值。一般的解决思路如下:

       function foo(num) {
if (num <= 1) {
return 1;
} else {
return num * foo(num - 1);
}
}
console.log(foo(5));//120

  但是别的地方引用该函数的时候,不免会发生错误:

        function foo(num) {
if (num <= 1) {
return 1;
} else {
return num * foo(num - 1);
}
}
console.log(foo(5));//120
let anotherFoo = foo
foo = null
console.log(anotherFoo(5)); // 报错 foo is not a function

  在写递归函数时使用 arguments.callee 可以避免这个问题。

        function foo(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
console.log(foo(5)); //120
let anotherFoo = foo
foo = null
console.log(anotherFoo(5)); //120

  不过,在严格模式下运行的代码是不能访问 arguments.callee 的,因为访问会出错。此时,可以使用命名函数表达式达到目的。

        let foo = (function f(num) {
if (num <= 1) {
return 1;
} else {
return num * f(num - 1);
}
});
console.log(foo(5));//120
let anotherFoo = foo
foo = null
console.log(anotherFoo(5));//120

  上面的代码创建一个函数表达式发 f()赋值给变量 foo ,即使函数赋值给了另一个变量,函数表达式f不变,因此递归就不会有调用的问题了。

写在最后

  以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长踩坑之路会持续更新一些工作中常见的问题和技术点。

js-arguments 函数参数对象详解的更多相关文章

  1. JavaScript进阶知识点——函数和对象详解

    JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...

  2. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  3. JS中的this对象详解

    JS中this关键字很常见,但是它似乎变幻莫测,让人抓狂.这篇文章就来揭示其中的奥秘. 借助阮一峰老师的话:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.这句话看似平常,可是要非常注意 ...

  4. Java 函数参数传递方式详解 分类: Java Game 2014-08-15 06:34 82人阅读 评论(0) 收藏

    转:http://zzproc.iteye.com/blog/1328591 在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式:  A. 是按值传递的?  B. ...

  5. Java函数参数传递方式详解

    在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式: A. 是按值传递的? B. 按引用传递的? C. 部分按值部分按引用? 此处暂不宣布正确答案,我们通过一个简 ...

  6. 【js】event(事件对象)详解

    1.事件对象 Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 什么时候会产生Event 对象呢? 例如: 当用户单击某个元素的时候,我们给这个元 ...

  7. JavaScript中的Function(函数)对象详解

    JavaScript中的Function对象是函数,函数的用途分为3类: 作为普通逻辑代码容器: 作为对象方法: 作为构造函数. 1.作为普通逻辑代码容器 function multiply(x, y ...

  8. Python中scatter函数参数用法详解

    1.scatter函数原型 2.其中散点的形状参数marker如下: 3.其中颜色参数c如下: 4.基本的使用方法如下: #导入必要的模块 import numpy as np import matp ...

  9. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

随机推荐

  1. php 设计模式 --桥接模式

    php抽象类和接口的区别 https://www.cnblogs.com/vinter/p/8716685.html 什么时候适合使用 --- 多个角色配合工作:抽象角色对应具体角色: <?ph ...

  2. python序列类型及一些操作

    序列分类 1.按存放的数据类型分类: 容器类型(能存放不同类型的数据):list.tuple.coolections.deque 扁平序列(只能存放一种类型的数据):str.bytes.bytearr ...

  3. Phalcon如何切换数据库《Phalcon入坑指南系列 三》

    本系列目录 一.Phalcon在Windows上安装 <Phalcon入坑指南系列 一> 二.Phalcon入坑必须知道的功能(项目配置.控制器.模型.增.删.改.查) 三.Phalcon ...

  4. 如何把springboot项目部署到tomcat上

    前言: 开始以为打包springboot项目为war包丢到tomcat上的webapps下面就可以访问controller层的路径了,可是调用接口却报404的错误,而打开8080的主页,不加路径却可以 ...

  5. 【问题记录】Java服务发起HTTPS请求报错:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException

    问题报错 今天上线了我开发的一个OAuth2单点登录客户端的实现,在测试系统验证没问题,到生产环境由于单点登录服务端HTTPS协议,报错如下: I/O error on POST request fo ...

  6. .Net Core利用反射动态加载类库的方法(解决类库不包含Nuget依赖包的问题)

    在.Net Framework时代,生成类库只需将类库项目编译好,然后拷贝到其他项目,即可引用或动态加载,相对来说,比较简单.但到了.Net Core时代,动态加载第三方类库,则稍微麻烦一些. 一.类 ...

  7. xmake v2.5.8 发布,新增 Pascal/Swig 程序和 Lua53 运行时支持

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  8. 无法解析的外部符号"void_cdecl caffe::caffe_gpu_dot<double>(int,double........)"

    将源码中的.cu文件添加到项目中即可,即使创建的就是NVIDIA的项目,也需要把这些个.cu文件添加进来

  9. Linux查找运行程序主目录

    1.查看程序所在PID netstat -lntup 2.根据PID查找程序所在目录 ll /proc/PID/exe 3.查找程序配置路径 /proc/PID/exe -t

  10. 【转载-Andrew_qian】stm32中断学习

    [转载]stm32中断学习 中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大 ...