9、类数组(arguments)与数组的区别与转换

9.1 定义

  • 数组是一个特殊对象,与常规对象的区别:
  • 当由新元素添加到列表中时,自动更新length属性
  • 设置length属性,可以截断数组
  • Array.protoype中继承了方法
  • 属性为'Array'
  • 类数组是一个拥有length属性,并且他属性为非负整数的普通对象,类数组不能直接调用数组方法。

常见的类数组对象

  • arguments
  • DOM方法的返回结果,比如document.getElementsByClassName()

浅析arguments对象

1. 定义
MDN——arguments对象

arguments 是一个对应于传递给函数的参数的类数组对象

function printArgs() {
  console.log(arguments);
}
printArgs("A", "a", 0, { foo: "Hello, arguments" });
//输出["A", "a", 0, Object]
//乍一看,结果是个数组,但并不是真正的数组,所以说 arguments 是一个类数组的对象

arguments 表示的内容:函数执行时传入函数的所有参数。在上面的例子中,代表了传入 printArgs 函数中的四个参数,可以分别用 arguments[0]arguments[1]… 来获取单个的参数。

2. arguments对象的操作及属性

  • typeof参数返回 ‘object’。
console.log(typeof arguments);    // 'object'
  • arguments 是个类数组对象,其包含一个 length 属性,可以用 arguments.length 来获得传入函数的参数个数
function func() {
    console.log("The number of parameters is " + arguments.length);
}
func(1, 2); // The number of parameters is " + 2
  • arguments 转数组的方法
//类数组转化为数组的方法:
Array.prototype.slice.call(arguments)
Array.prototype.slice.apply(arguments)
[].slice.call(arguments) //调用了空数组的slice方法,而没有从Array的原型层面调用。
[].concat.apply([],arguments)
Array.from(arguments) // es6  推荐
Array.of(1,2,3,4); //[1,2,3,4]  es6

slice 方法得到的结果是一个数组,参数便是 arguments。事实上,满足一定条件的对象都能被 slice 方法转换成数组。看个例子:

//obj条件:1) 属性为 0,1,2...;2) 具有length属性(是类数组);
const obj = { 0: "A", 1: "B", length: 2 };
const result = [].slice.call(obj);
console.log(Array.isArray(result), result); //true ["A", "B"]

注意:不要将函数的 arguments 泄露或者传递出去,否则性能损失很大

// Leaking arguments 例子:
function getArgs() {
  const args = [].slice.call(arguments);
  return args;
}
//改进后
function getArgs() {
  const args = new Array(arguments.length);
  for(let i = 0; i < args.length; ++i) {
    args[i] = arguments[i];
  }
  return args;
}
  • 利用 arguments 模拟重载
function add(num1, num2, num3) {
  if (arguments.length === 2) {
    console.log("Result is " + (num1 + num2));
  }
  else if (arguments.length === 3) {
    console.log("Result is " + (num1 + num2 + num3));
  }
}
add(1, 2); //Result is 3
add(1, 2, 3)  //Result is 6
  • ES6 中的 arguments

1. 扩展操作符

扩展操作符可以将 arguments 展开成独立的参数

function func() {
  console.log(...arguments);
}
func(1, 2, 3); // 1 2 3

2. Rest参数

Rest 参数表示除了明确指定剩下的参数集合,类型是 Array

function func(firstArg, ...restArgs) {
  console.log(Array.isArray(restArgs));
  console.log(firstArg, restArgs);
}	
func(1, 2, 3); 
//true
//1 [2, 3]

9.2 类数组与数组的区别

本质:类数组是简单对象,它的原型关系与数组不同。

相同点:

  • 都可用下标索引访问每个元素
  • 都有length属性

不同点:

  • 数组对象类型为Array,遍历数组可以用for...in..for循环
  • 类数组对象类型为Object,遍历类数组只能用for循环
// 原型关系和原始值转换
let arrayLike = {
    length: 10,
};
console.log(arrayLike instanceof Array); // false
console.log(arrayLike.__proto__.constructor === Array); // false
console.log(arrayLike.toString()); // [object Object]
console.log(arrayLike.valueOf()); // {length: 10}

let array = [];
console.log(array instanceof Array); // true
console.log(array.__proto__.constructor === Array); // true
console.log(array.toString()); // ''
console.log(array.valueOf()); // []

参考文章

JavaScript arguments 对象全面介绍

你可能感兴趣的:(JavaScript)