1. arguments是什么
- 当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。

特点:
-
arguments 是一个 对应于 传递给函数的参数 的 类数组(array-like)对象
array-like意味着它不是一个数组类型,而是一个对象类型: -
但是它却拥有数组的一些特性,比如说length,比如可以通过index索引来访问;
-
但是它却没有数组的一些方法,比如forEach、map等
在调用函数的时候,浏览器每次都会传递两个隐形参数:
1.函数的上下文对象this
2.封装实参的对象arguments
arguments是一个类数组对象,不是一个对象
arguments instanceof Array //false
Array.isArray(argumetns)//false
它可以通过索引来操作数据,可以获取长度
在调用函数时,我们所传递的实参都会封装到arguments中保存
arguments.length可以获得实参长度
即使不定义实参,也可以通过aguments来使用实参
只不过比较麻烦,
arguments[0]表示第一个实参
3.arguments实现里面有一个属性叫做callee
这个属性对应一个函数对象,就是当前正在指向的函数的对象
arguments.callee == fun // true
2. arguments的基本使用
function foo(num1, num2, num3){
console.log(num1, num2, num3);
console.log(arguments);
}
foo(10, 20, 30, 40, 50)
//10 20 30
//Arguments(5) [10, 20, 30, 40, 50, callee: ƒ, Symbol(Symbol.iterator): ƒ]
/*虽然看起来这个函数只有3个形参
但是函数内部会将所有调用函数时候传入的参数放到一个类数组对象里面
类数组对象中(长的像是一个数组, 本质上是一个对象): arguments
这些东西是放到ao里面的,未解析时ao是以下
var ao = {
num1 : undefined,
num2 : undefined,
num3 : undefined,
arguments : {},
}
解析完之后
var ao = {
num1 : 10,
num2 : 20,
num3 : 30,
arguments : {'0' : 10, '1': 20, '2': 30, '3' : 40, '4': 50}
}
*/
function foo1(num1, num2, num3){
//常见的对argumetns的操作有三个
//1.获取参数的长度
console.log(arguments.length)//5
// 2.根据索引值获取某一个参数
console.log(arguments[2]) //30
console.log(arguments[3]) //40
console.log(arguments[4]) //50
// 3.callee获取当前arguments所在的函数
console.log(arguments.callee)
// arguments.callee() //这样写会无限调用这个函数(递归)
}
foo1(10, 20, 30, 40, 50)
3. 将arguments转成数组类型
//1.自己遍历
function foo(num1, num2){
var newArray = [];
for(var i = 0; i < arguments.length; i++){
newArray.push(arguments[i] * 10);
}
console.log(newArray); //(5) [100, 200, 300, 400, 500]
//2.Array.prototype.slice将arguments转成arr(可遍历对象)
//slice的本质是遍历这个可迭代的对象
var newArr2 = Array.prototype.slice.call(arguments)
console.log(newArr2)
var newArr3 = [].slice.call(arguments)
console.log(newArr3)
//es6语法
//from() 方法从具有 length 属性或可迭代对象的任何对象返回 Array 对象。
const myArr = Array.from("ABCDEFG");
console.log(myArr);//(7) ['A', 'B', 'C', 'D', 'E', 'F', 'G']
var newArrays = [...arguments];
console.log(newArrays);//(5) [10, 20, 30, 40, 50]
}
foo(10, 20, 30, 40, 50)
//额外补充的知识点: Array中的slice实现
//slice的本质就是迭代元素,伪数组也可以
Array.prototype.hyslice = function(startIndex, endIndex){
console.log(this);//这里的this就是调用这个函数的那个对象/数组
var arr = this;
var newArr = [];
startIndex = startIndex || 0;
endIndex = endIndex || arr.length;
for(var i = startIndex; i < endIndex; i++){
newArr.push(arr[i])
}
return newArr
}
var nums = [0, 1, 2, 3, 4];
console.log(nums.hyslice());
//拿到一个函数Function的对象foo去调aaa
// Function.prototype.aaa = function(){...}
// foo.aaa()
//如果没有函数的对象,如何使用aaa这个方法??
//直接Function.prototype.aaa()这么去做
//实际上下面两种方法是一样的
var result = nums.hyslice(1,3);
console.log(result);//(2) [1, 2]
var result2 = Array.prototype.hyslice.call(nums, 1, 3)
console.log(result2);//(2) [1, 2]
4 箭头函数中没有arguments
arguments是es5的老东西了,不推荐使用
//1.案例一:
/* var foo = () => {
console.log(artuments);
}
foo() */
//tUncaught ReferenceError: artuments is not defined
//对于浏览器来说,全局里面没有arguments,node里面的全局作用域有
//2.案例二:
//没有找到arguments怎么办,就去上层作用域中去寻找
//找到上层作用域的arguments
function foo(){
var bar = () =>{
console.log(arguments);
}
return bar
}
var fn = foo(123);
fn()
//Arguments [123, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//3.案例三:
//如果没有arguments,但是我又想拿到参数
//答案是使用剩余参数
var foo1 = (num1, num2, ...args) => {
console.log(args) //(3) [30, 40, 50]
}
foo1(10, 20, 30, 40, 50)
网友评论