类数组 arguments

// 情况1 (正常形参和实参)
let fun1 = function(param) {
  // console.log(arguments); // 打印出[Arguments] { '0': 12 } { '0': 12 }
  // 可以用 Array.from() 转换成数组 或者for in 或者 扩展运算 ...
  console.log(Array.from(arguments)); // 打印出 [12]
};
fun1(
12);
// 情况2(实参大于形参)
let fun2 = function(param) {
  console.log(arguments); // [Arguments] { '0': 12, '1': 1, '2': 2 }
  console.log([...arguments]); // [ 12, 1, 2 ]
};

fun2(12, 1, 2);
// 情况3(刻意改变length)
let fun3 = function(param) {
  arguments.length = 3;
  console.log(arguments); // [Arguments] { '0': 12 }
  console.log([...arguments]); // [ 12, undefined, undefined ]
};
fun3(12);
/* 说明 */
// arguments 内部接收到了参数后 实际是这样的数据结构
{
  0: '12',
  1: '1',
  2: '2',
  length: 3
 }

栗子1

var length = 4;
function callback() {
  console.log(this.length);
}

const object = {
  length: 5,
  method() {
    arguments[0]();
  },
};

object.method(callback, 1, 2);

/* 结果 */
arguments[0]()是arguments对象上的回调的方法调用,所以回调内部的参数等于arguments。
所以 callback()中的this.length与arguments.length相同,即3

 栗子2

我们使用 getElementsByTagName() 方法获取这些列表元素。

document.getElementsByTagName('li');
它返回 HTMLCollection 是类数组对象

它和数组类似,我们试着使用 forEach 来遍历它:

document.getElementsByTagName('li').forEach(() => {
 // Do something here..
})

在类数组对象上调用 forEach 发生错误

为什么会这样?这是因为 HTMLCollection 并不是数组,而是 类数组 对象,所以不能使用 forEach 来遍历它。

其原型(proto)是 Object

这里就需要用到 Array.from() 方法了,Array.from() 能将类数组对象转换为数组,进而能够在它上面执行所有数组操作。(你new Array(6)这样创建的也需要from下 不然不能直接遍历)

const collection = Array.from(document.getElementsByTagName('li'))
这时的 collection 是一个数组

简写

不要在函数体内使用 arguments 变量,使用 rest 运算符(...)代替。因为 rest 运算符显式表明你想要获取参数,

而且 arguments 是一个类似数组的对象,而 rest 运算符可以提供一个真正的数组。
// bad function concatenateAll() { const args = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(...args) { return args.join(''); } —— 来自阮一峰 ECMAScript 6 入门
posted @ 2021-03-11 11:14  Model-Zachary  阅读(55)  评论(0编辑  收藏  举报