Javascript学习笔记之函数篇(四):arguments 对象


Posted in Javascript onNovember 23, 2014

每一个 Javascript 函数都能在自己作用域内访问一个特殊的变量 - arguments。这个变量含有一个传递给函数的所有参数的列表。
arguments 对象不是一个数组。尽管在语法上它跟数组有相同的地方,例如它拥有 length 属性。但它并不是从 Array.prototype 继承而来,实际上,它就是一个对象。
因此,我们不能直接对 arguments 使用一些数组的方法,例如 push, pop 或 slice 等。 所以为了使用这些方法,我们就需要将其转换为一个真正的数组。

转化为数组

下面的代码将会返回一个包含 arguments 对象所有元素的数组。

Array.prototype.slice.call(arguments);
由于转化的速度很慢,所以在性能要求严格的程序中不建议这样做。

传递参数

下面是一种比较推荐的方法,将 arguments 对象从一个函数传递到另一个函数。

function foo() {

    bar.apply(null, arguments);

}

function bar(a, b, c) {

    // do stuff here

}

另外还有一个比较巧妙的方法,就是同时使用 call 和 apply 快速创建一个解绑的外层方法。

function Foo() {}

Foo.prototype.method = function(a, b, c) {

    console.log(this, a, b, c);

};

// Create an unbound version of "method" 

// It takes the parameters: this, arg1, arg2...argN

Foo.method = function() {

    // Result: Foo.prototype.method.call(this, arg1, arg2... argN)

    Function.call.apply(Foo.prototype.method, arguments);

};

函数形参和 arguments 属性的关系

arguments 对象为它自身属性和函数的形参都创建了 getter 和 setter 方法。
因此,修改函数的形参会影响对应的 arguments 对象的属性值,反之亦然。

function foo(a, b, c) {

    arguments[0] = 2;

    a; // 2

    b = 4;

    arguments[1]; // 4

    var d = c;

    d = 9;

    c; // 3

}

foo(1, 2, 3);

性能问题

arguments 只在两种情况下不会被创建,一是在函数内部被声明为局部变量,二是当做函数的形参。其他情况,arguments 对象总是会被创建。
由于 getter 和 setter 方法总是会随着 arguments 对象的创建而创建,因此使用 arguments 对性能本身几乎没有影响。
然而,有一种情形会严重影响 Javascript 的性能,那就是使用 arguments.callee。

function foo() {

    arguments.callee; // do something with this function object

    arguments.callee.caller; // and the calling function object

}

function bigLoop() {

    for(var i = 0; i < 100000; i++) {

        foo(); // Would normally be inlined...

    }

}

在上述代码中,foo 函数不再是一个简单的内联扩展,因为它需要知道它自身以及它的调用者(caller)。这不仅抵消了内联扩展所带来的性能提升,同时也破坏了函数的封装性,因为函数本身可能需要依赖于一个特定的调用背景。
因此,建议大家尽量不要使用 arguments.callee。

以上就是关于Javascript arguments 对象的全部内容了,小伙伴们是否了解透彻呢,简单的说

arguments指函数的参数对象(指实际传入的参数)
arguments.length指函数的参数对象的长度
arguments[i]指第i个参数的值(第一个为0)

Javascript 相关文章推荐
关于 byval 与 byref 的区别分析总结
Oct 08 Javascript
javascript 一些用法小结
Sep 11 Javascript
jQuery EasyUI API 中文文档 - Tree树使用介绍
Nov 19 Javascript
JavaScript检测实例属性, 原型属性
Feb 04 Javascript
js仿黑客帝国字母掉落效果代码分享
Nov 08 Javascript
jQuery实现按钮点击遮罩加载及处理完后恢复的效果
Jun 07 Javascript
javascript实现多张图片左右无缝滚动效果
Mar 22 Javascript
JavaScript实现与使用发布/订阅模式详解
Jan 19 Javascript
Webpack4 使用Babel处理ES6语法的方法示例
Mar 07 Javascript
javascript数据类型中的一些小知识点(推荐)
Apr 18 Javascript
详解vue 组件注册
Nov 20 Vue.js
vue完美实现el-table列宽自适应
May 08 Vue.js
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 #Javascript
js实例属性和原型属性示例详解
Nov 23 #Javascript
JS常用函数使用指南
Nov 23 #Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 #Javascript
理解jQuery stop()方法
Nov 21 #Javascript
JS中三目运算符和if else的区别分析与示例
Nov 21 #Javascript
node.js使用npm 安装插件时提示install Error: ENOENT报错的解决方法
Nov 20 #Javascript
You might like
php UTF-8、Unicode和BOM问题
2010/05/18 PHP
php字符串截取函数用法分析
2014/11/25 PHP
php实现读取内存顺序号
2015/03/29 PHP
学习php设计模式 php实现模板方法模式
2015/12/08 PHP
PHP 获取指定地区的天气实例代码
2017/02/08 PHP
php把字符串指定字符分割成数组的方法
2018/03/12 PHP
javascript prototype原型操作笔记
2009/12/07 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
JQuery替换DOM节点的方法
2015/06/11 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
JavaScript如何一次性展示几万条数据
2017/03/30 Javascript
微信小程序 数据绑定及运算的简单实例
2017/09/20 Javascript
初学者AngularJS的环境搭建过程
2017/10/27 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
2018/12/03 Javascript
layui table 列宽百分比显示的实现方法
2019/09/28 Javascript
解决vue v-for src 图片路径问题 404
2019/11/12 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
2020/09/21 Javascript
针对Vue路由history模式下Nginx后台配置操作
2020/10/22 Javascript
简单介绍Python下自己编写web框架的一些要点
2015/04/29 Python
Python学习_几种存取xls/xlsx文件的方法总结
2018/05/03 Python
Mac在python3环境下安装virtualwrapper遇到的问题及解决方法
2019/07/09 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
2019/11/16 Python
Anaconda 查看、创建、管理和使用python环境的方法
2019/12/03 Python
OpenCV哈里斯(Harris)角点检测的实现
2020/01/15 Python
Pycharm debug调试时带参数过程解析
2020/02/03 Python
Django获取model中的字段名和字段的verbose_name方式
2020/05/19 Python
澳大利亚领先的睡衣品牌:Peter Alexander
2016/08/16 全球购物
法国时尚品牌乐都特瑞士站:La Redoute瑞士
2016/09/05 全球购物
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
Luxplus瑞典:香水和美容护理折扣
2018/01/28 全球购物
俄罗斯奢侈品牌衣服、鞋子和配饰的在线商店:INTERMODA
2020/07/17 全球购物
高校自主招生自荐信
2013/12/09 职场文书
电焊工岗位职责
2014/03/06 职场文书