在实际项目开发中,目前还是很少使用到JavaScript 中的arguments对象,那么它到底是干什么用的呢

arguments是JavaScript中的一个类数组对象,它代表传给一个正在执行的函数function的参数列表。

看完这个定义,需要明白,它是一个对象,不是一个数组,但是它这个对象却又类似数组,也就是说样子和数组类似. 那它的内容,它里面的内容是传递给正在执行的函数Function的参数列表

上面都特别强调,是 正在执行的函数function,这也就是说,arguments对象只有函数已经开始执行时,才可以使用,才能取到值。 所以, arguments对象存储的是实际传递给函数的参数,而不是函数声明时所定义的参数列表

我们来看一个例子,能够更直观的理解它

function showArgs()
{
console.log(arguments);
} showArgs("a","1",{ test: "only for test" }); 执行结果如下 ["a","1",Object]

上面的函数showArgs作用是输出它的参数列表,当我们调用它 showArgs("a","1",{ test: "only for test" }) 时,可以看到,它总共包括3个参数,分别是”a“,"1",{ test: "only for test" }, 其中,第三个{ test: "only for test" }是个object, javascript无法直接输出它,所以就输出了object

如果要访问其中某一个参数呢,arguments提供和数组一样的方式来访问单个参数,也就是使用下标arguments[0],arguments[1]来访问.

形式应该是这样的 [function].arguments[n]  function在这里可以省略,表示的是当前正在执行的Function对象的名字

在上面的函数中, arguments[0] = "a", arguments[1] = "1" , arguments[2] = {test: "only for test"}

接下来,我们来看看arguments对象的一些属性

1. length属性

上面说了arguments是个类数组对象,它和数组一样,也有一个length属性,我们可以通过arguments.length来获得传入函数的参数个数

2. callee属性

arguments.callee的值,是当前正在被执行的函数,也就是说是当前这个arguments它所在的函数.  我们上面论述了,arguments在函数被调用时才会有效,它才存在。 因此,在函数没有被调用时 arguments.callee是不存在的.

另外 特别注意  在JavaScript的严格模式下面, arguments.callee是不可以使用的

3. arguments转成真正的数组

我们上面说了,arguments是一个类数组的对象,但不是数组,它虽然也有和数组一样的length属性,也可以像数组一样采用arguments[n]下标形式进行访问。 但它并不是数组,那么我们可以把它转换为数组吗 ? 答案是可以的

采用如下方法    Array.prototype.slice.call(arguments);  还可以用一个简易的写法 [].slice.call(arguments);

事实上, slice方法可以用来把满足一定条件的对象转换成数组, 这个在这里我们就不详细论述了

我们来看一个例子

function TestArguments()
{
var testArray = Array.prototype.slice.call(arguments); //把arguments转换成了真正的数组 // var testArray = [].slice.call(arguments); //也可以这样简写,也是把arguments转换成数组
var sum = 0; testArray.forEach( //可以调用数组的forEach方法
function(value)
{
sum += value; }); return sum;
}

当然,也可以调用JavaScript中的Array.from()方法来把arguments转换为真正的数组

JS中的Array.from()方法就是用来从一个类似数组或者可迭代对象中创建一个新的数组实例.  我们还是来看一个例子

function testfunc()
{
return Array.from(arguments);
} testfunc(7,8,9); //输出 [7,8,9]

 4.  用arguments来模拟重载

我们知道C# 语言中有重载,但是JavaScript中没有重载. 我们举一个例子来说明JavaScript中没有重载

function add(arg1,arg2)   //第1个add方法
{
console.log("第一个add方法");
return arg1 + arg2; } function add(arg1,arg2,arg3) //第2个add方法
{
console.log("第2个add方法");
return arg1 + arg2 + arg3; } add(1,2); //输出 第2个add方法
add(1,2,3); //输出 第2个add方法

在上面的例子中,我们可以看到,函数调用的始终都是第2个add方法, 因为JavaScript是按照顺序来执行的. 而不是像C#中那样,存在函数重载,会根据参数的不同调用不同的重载函数

但是我们如果想实现这样的重载效果,有没有方法来实现呢。 思考一下,它本质上就是根据参数个数不同输出不一样的结果,而实际传入的参数个数是可以通过arguments来判断的。

我们来写一个例子

function add(arg1,arg2,arg3)
{
if(arguments.length === 2)
{
console.log(arg1 + arg2);
}
else if (arguments.length === 3)
{
console.log(arg1 + arg2 + arg3);
} } add(5,5); //输出 10
add(5,5,5); // 输出 15

 5. arguments与默认参数

我们知道C#中有默认参数,我们来看看C#中默认参数的例子

public string add(int a, int b = , int c = )
{
return a + b + c;
}

在这个例子中,传入的参数b的默认值为10, c的默认值为15. 也就是说我们在调用add函数时,如果没有给b和c传值的话,就会使用它们的默认值10和15

那么,在JavaScript中,有没有同样的参数默认值设定呢,答案是有的,我们来看一个例子

function testfunc(firstArg = 0, secondArg =1)
{
console.log(firstArg,secondArg);
} testfunc(100); //输出 100 1

看上面这个JavaScript函数,有两个参数firstArg,secondArg. 两个参数都有默认值,当调用该函数testfunc(100) 时,传入了一个参数100,自然就是覆盖了第一个参数,第2个参数没有传入,自然会取它的默认值1,所以输出100,1

那这个又跟我们这篇博客中的arguments有什么关系的,我们来把它修改一下看看

function testfunc(firstArg = 0, secondArg =1)
{
console.log(arguments[0],arguments[1]);
console.log(firstArg,secondArg);
} testfunc(100); //输出
100 undefined
100 1

上面可以看到,当调用函数testfunc(100) 时, console.log(arguments[0],arguments[1]) 输出的是 100 undefined, 也就是说arguments[1]还是没有值,它没有取默认传入的参数secondArg=1

这样符合arguments的定义,arguments指的是调用函数时,实际传入的参数,在上面例子中,调用函数testfunc(100), 实际传入的参数就是只有一个100. 由此可见,默认参数对arguments完全没有影响

JavaScript学习系列3 -- JavaScript arguments对象学习的更多相关文章

  1. scrapy爬虫学习系列四:portia的学习入门

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  2. JavaScript 没有函数重载&Arguments对象

    对于学过Java的人来说.函数重载并非一个陌生的概念,可是javaScript中有函数重载么...接下来我们就进行測试 <script type="text/javascript&qu ...

  3. JavaScript学习系列8 - JavaScript中的关系运算符

    JavaScript中有8个关系运算符,分别是 ===, !===, ==, !=, <, <=, >, >= 1. 恒等运算符 (===) ===也叫做 严格相等运算符,它要 ...

  4. JavaScript学习系列7 -- JavaScript中的运算符

    今天,我们来说一说JavaScript中的运算符,首先我们来讲一讲 一元运算符 JavaScript中的一元运算符有以下几种 1. delete delete 运算符主要用于删除对以前定义的对象属性或 ...

  5. JavaScript学习系列6 -- JavaScript中的垃圾回收(内存释放)

    程序开发中,涉及到的内存生命周期基本是一样的,分为以下三步 1. 分配需要的内存 2. 使用分配到的内存 3. 释放其内存    ----什么时候释放内存,以及需要释放哪些变量的内存, 就是垃圾回收机 ...

  6. JavaScript学习系列4 ----- JavaScript中的扩展运算符 三个点(...)

    在JavaScript中, ES6开始有rest参数 和 三个点扩展运算符 (spread运算符) 我们来看看他们各自的用处 1. rest参数 rest参数的形式为 ...变量名          ...

  7. Javascript可变长度参数列表 - Arguments对象

    在一个函数体内,标识符arguments具有特殊含义. Arguments对象是一个类似数组的对象 eg: 验证函数参数的正确数目 function f(x, y, z) { if (argument ...

  8. LINQ学习系列-----1.4 匿名对象

    本篇内容接着上一篇继续讲述,本篇简单讲解匿名对象 一.匿名对象介绍              上代码: var result=new { ID=, Name="张三", Age= ...

  9. JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

    我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Jav ...

随机推荐

  1. 左侧图片 右侧块的实现方法---解决3像素bug的一种解决方案,不用浮动用绝对定位和margin-left

    google的实现方式是: <div class="mw"> <a href="/" id="mlogo">  &l ...

  2. IE浏览器和CSS盒模型【转】

    总结:css盒模型在不同浏览器之间(例如:ie和其他浏览器 如火狐)的差异只存在于ie6之前的版本中,如ie5.在ie6下, Internet Explorer 在标准模式下渲染时使用了 CSS 规范 ...

  3. 从输入url到浏览器呈现网页发生了什么?

    大致能分成两个部分:网络通信与页面渲染 一.网络通信 互联网各个网络设备间的通信均基于TCP/IP协议,此协议将整个过程进行分层,由上至下分别为: 应用层.传输层.网络层和数据链路层 1.输入URL ...

  4. poj 1258 最小生成树 模板

    POJ 最小生成树模板 Kruskal算法 #include<iostream> #include<algorithm> #include<stdio.h> #in ...

  5. Jboss添加Windows服务,同时定期重启

    一.添加成Windows服务 进入目录 \wildfly-9.0.2s - All\bin\service\ 编辑 service.bat,修改一下参数 set SHORTNAME=SAMEXAppS ...

  6. python第九篇:Python进程

    Python进程 接下来我主要按照下图中思维导图上的关键点对进程和线程进行一个总结 进程知识点总结:   一.Python进程 1.概念 程序和进程: 程序:是可执行文件,是静态的,占据磁盘空间,程序 ...

  7. SpringMVC 文件上传及下载

    首先需要导入jar包 创建一个jsp页面 package cn.happy.Controller; import java.io.File; import javax.servlet.http.Htt ...

  8. java:Properties属性文件概念

    java:Properties属性文件概念 在java之前的国际化程序中提出了一个属性文件的概念,属性文件的后缀是:*.properties,那么在java中提供了意个属性文件的专门操作类,Prope ...

  9. Linux中redis主从配置

    假设要在6380开启redis 1.添加配置文件:复制redis.conf为redis_6380.conf 2.修改配置文件:修改redis_6380.conf中port.pidfile 3.防火墙: ...

  10. 两个stack实现一个queue

    package com.hzins.suanfa; import java.util.Stack; /** * 两个stack实现一个queue * @author Administrator * * ...