arguments
arguments,这个鬼东西还是很重要的,一般他是用在函数里,他函数里无论是实参还是形参,都能在它里面包含。
据MDN:
arguments 是一个类数组对象。代表传给一个function的参数列表
我们先看看arguments的形式吧,代码如下:
curryStore();
function curryStore(a, c) {
console.log(arguments);
}
从上面的日志来看,有个calleee函数指向当前执行的函数。
,这个函数的length其实就是形参的个数。其实在严格模式下,该函数是被移除的。当我们给函数的形参设置初始默认值,该函数也是会被移除的。
curryStore(1);
function curryStore(a, c) {
a = 0;
console.log(arguments);//arguments[0]的值会变为0;参数值覆盖。
}
比如我将上面的curryStore()
的函数调用设置三个实参curryStore(1,2,3
等,打印出的日志可以看到,length值为4,也就表示函数存在四个实参。
再比如:
curryStore(1, 2, 3, 4);
function curryStore(a = 55, c) {
a = 0;
console.log(arguments[0]);
}
比如向上述你认为该答案为多少呢,其实打印后的结果是:1.其实内部的全局a变量并未没有将其覆盖。如果我将全局a变成局部变量,结果又该如何呢?结果还会是1。若果将设置的参数初始值,给拿掉,重复上述的操作,结果会一样吗?未设置参数初始值时,他就会随着变量值变化而变化。将a定义在函数内部赋值,意思将函数的参数的只改变。a定义在函数外部赋值该变量,是无法将函数参数的值改变。
curryStore(1, 2, 3, 4);
c = 5;
function curryStore(a, c, d) {
a = 0;
var d = 7;
console.log(arguments[0], arguments[1],arguments[2])//a=0, c = 2, d = 7
}
上面两处代码,也是为了,加强对参数的理解,a=55,为了调调a为函数的参数,他的值只接受函数调用时传的值。没有设置初始值,a的改变,也就会代表函数参数的值需要变化。这种现象的原理可以采用创建oa对象,找形参和变量声明,形参和实参一,找函数申明。这几个过程去解释。具体请见[1]
关于预编译(v8引擎),本文章就不细讲了。还是回到arguments的正题上吧,其实js新特性中,函数的参数,还可以采用函数 参数解构的方式去使用;
a(1,2,4); function a(...args){ console.log(args);//[1,2,4] type;array}
接下来为大家介绍关于arguments类数组的数组化的几个方法。
- 遍历法:
遍历法,顾名思义,就是将arguments进行遍历,一个一个装进数组里;a = [1,2 34,7]; function a(){ var b = []; for(var i =0; i<arguments.length; i++){ b.push(arguments[i]) } return b ; }
- 解构法:
解构法,利用js新特性,数组解构赋值
a(1,2,3,4);
function a(...args){
const [...b] = arguments;
[...arguments]
}
- 装箱转化法
装箱转化法,利用call和apply的装箱机制,进行实现的。
[1] . apply: 利用apply传参方案,
此方法的缺陷,在采用number类型作为参数时,会有个小问题产生,当实参数只有一位时,产生的数组会将传参数字大小作为该数组的长度
解决这个问题的产生做个判断就好了
产生的原因:js构造函数特性导致的
[2]. 利用数组的原型prototype:var b if(arguments.length===1 && typeof arguments[0] === 'number'){ b = [arguments[0]]; }else{ b = Array.apply(null, arguments); } console.log(b);
以上就是我个人对arguments的理解,其实大家想要精通可以将MDN文档给研究一遍。console.log(Array.prototype); var b = Array.prototype.slice.apply(arguments); var b =Array.prototype.concat.apply([], arguments) console.log(b);