欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

javascript的arguments对象的方法技巧

来源:本站整理 作者:佚名 时间:2016-03-03 TAG: 我要投稿

1、什么是arguments
arguments 是是JavaScript里的一个内置对象,它很古怪,也经常被人所忽视,但实际上是很重要的。所有主要的js函数库都利用了arguments对象。所以agruments对象对于javascript程序员来说是必需熟悉的。在javascript函数体内,标识符arguments具有特殊含义。它是调用对象的一个特殊属性,用来引用Arguments对象。Arugments对象就像数组,注意这里只是像并不是哈。
javascript函数体内,arguments像数组(并不是真的数组,是一个Arguments对象,再次强调)一样,有length属性,可以代表传给函数的参数的个数。
javascript中Arguments对象是函数的实际参数,arguments对象的长度是由实参个数而不是形参个数决定的。形参是函数内部重新开辟内存空间存储的变量,但是其与arguments对象内存空间并不重叠。
js不会主动为你判断你到底给函数传了多少个参数,如果你多传了,多余的部分就没有被使用,如果你少传了,那么没传的参数值就是undefined.所以我们可以借助arguments的length属性来检测调用函数时是否使用了正确数目的实际参数,因为javascript是不会为你做这些事的
function f(x,y,z)
{
 //首先检查传递的参数数量是否正确
 if(arguments.length != 3)
 {
  throw new Error("function f called with " + arguments.length + "arguments");
 }
 //下面运行真正的函数
}
2、arguments创建可变参数列表函数
arguments还为我们提供了这样一种可能,就是为一个函数传任意数目的实际参数:
比如说,我想用一个display()函数来计算每个公司的员工工资总额,对,没错,你传多少参数都行,但是前提是你要传数字,因为我在函数内部懒得判断了。
 function display(){
  var sum=0; //总额
  for(var i=0;iarguments.length;i++){
   sum+=arguments[i];
  }
  document.write(sum+'
');
 }
 //A公司
 display(10000,2000,5000);
 //B公司
 display(1000,2000,5000,8000,10000);
怎么样?这个方法很巧妙吧?
说明一下arguments与真正传的形式参数是一致的:
对于arguments和值都存在的情况下,两者值是同步的改变其中一个值,即改变了二者所有的值
function f(a, b, c){
 alert(arguments.length); // result: "2"
 a = 100;
 alert(arguments[0]);  // result: "100"
 arguments[0] = "qqyumidi";
 alert(a);     // result: "qqyumidi"
 alert(c);     // result: "undefined"
 c = 2012;
 alert(arguments[2]);  // result: "undefined"
}
f(1, 2);
3、永远不要修改arguments对象
函数中声明的参数和arguments之间的联系很脆弱,每个声明的参数实际上只是对arguments对象中对应位置的一个引用。
值得注意的是,在ES5的strict mode中,函数声明的参数并不会引用arguments:
function strict(x) {
 "use strict";
 arguments[0] = "modified";
 return x === arguments[0];
}
function nonstrict(x) {
 arguments[0] = "modified";
 return x === arguments[0];
}
strict("unmodified"); // false
nonstrict("unmodified"); // true
正因为在strict和非strict模式下,函数声明的参数和arguments的关系不一致,所以为了避免出现问题,不去修改arguments对象才是最安全的做法。
如果确实需要修改arguments对象,那么可以首先赋值一份arguments对象:
var args = [].slice.call(arguments);
当slice方法不接受任何参数的时候,就会执行复制操作,得到的args也是一个真正的数组对象。同时,args和函数声明的参数之间也没有任何联系了,对它进行操作是安全的。
4、一个变量来保存arguments的引用
假设需要一个API用来遍历若干元素,像下面这样:
var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);
it.next(); // 1
it.next(); // 4
it.next(); // 1
相应的实现可以是:
function values() {
 var i = 0, n = arguments.length;
 return {
  hasNext: function() {
   return i  n;
  },
  next: function() {
   if (i >= n) {
    throw new Error("end of iteration");
   }
   return arguments[i++]; // wrong arguments
  }
 };
}
但是执行的实际情况却是:
var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);
it.next(); // undefined
it.next(); // undefined
it.next(); // undefined
原因在于:对于arguments对象的赋值是隐式完成的。在next方法内部,使用了arguments,然而此arguments和values方法开始处的arguments并不是一个对象。这里的arguments对象是函数next()的。
解决方法也很简单,就是将需要访问的arguments使用另外一个变量进行引用。然后通过闭包的性质在其嵌套的函数中进行访问就可以了,像下面这样:
function values() {
 var i = 0, n = arguments.length, a = arguments;
 return {
  hasNext: function() {
   return i  n;
  },
  next: function() {
   if (i >= n) {
    throw new Error("end of iteration");
   }
   return a[i++];
  }
 };
}
var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载