数组篇章

122 阅读5分钟

思维脑图获取链接 不妨给个start,持续输出有趣的东西。

声明数组

  1. var arr = [] 推荐, 使用数组字面量
  2. var arr = new Array() 通过系统内置的构造函数 Array
  3. var arr = Array() 不使用, 虽然可以, 但是不推荐使用

三种声明方式的数组都继承: Array.prototype 也就是说, 所有的数组实例对象都能使用 Array.prototype 上的所有方法, 同理: 对象类型也是这样的。

Array 与 Object 类型的关系

Array 是特殊的 Object

对象底层也是用 obj[key] 来取值的, 数组取值就是利用这种机制

// 数组的每一个元素对应了一个下标(也叫索引), 下标从0开始
var arr = [1, 2, 3];
// 索引值: [0, 1, 2];
​
// 模拟数组:
var obj = {
    0: 1,
  1: 2,
  2: 3,
  length: 3,
};
​
console.log(arr[1] === obj[1]); //truearr.hello = "world";
obj.hello = "world";
console.log(arr.hello === obj.hello); // true

稀松数组

数组元素中含有 empty 的数组叫做稀松数组

  1. 如果数组最后一位是 empty 则不会计算最后一位
  2. 如果使用构造函数来创建数组, 就不能有 empty 的元素, 因为 new Array, 传的是参数, 参数不能随便乱写, 会语法错误
var arr = [,1,2,,,3,4,]; // length: 7
console.log(arr);

Array 构造函数创建数组注意点

  1. 如果只有一个参数, 并且是一个 正整数 (比如: 3) , 它会直接创建一个长度为3, 元素全部是 empty 的数组
  2. 如果只有一个参数, 这个数是一个number类型, 但是不是一个 正整数 就会报错, 比如 Array(-5) Array(1.2)
  3. 如果只有一个参数, 并且这个数不是number类型, 他会创建一个数组, 并且把这个参数作为数组的第一个元素
  4. 如果有多个参数, 他会直接把这些参数全部放到一个数组中, 然后返回
var arr1 = new Array(3); // [ empty, empty, empty ]
var arr2 = new Array(-1); // 报错: RanageError: Invalid array length
var arr3 = new Array(1.2); // 报错: Invalid array length
var arr4 = new Array('a'); // ['a']
var arr5 = new Array(1, 2, 3, 4); // [ 1, 2, 3, 4 ]

Array 原型上的方法(改变原数组)

数组的方法从哪里来的?

结论:所有方法都是继承自 Array 构造函数的原型对象(Array.prototype)上的方法。

原因如下:

  1. 所有的数组实例对象都是有 Array 这个构造函数创建的
  2. 实例对象本身没有这些函数, 就会沿着原型链去查找
  3. 实例对象去找其构造函数的原型对象上的方法, 肯定是能找到的

添加元素:push/unshift

返回值:新的 length

var arr = [2,3];
​
console.log(arr.unsfhit(1)); // 3
console.log(arr);  // [1, 2, 3]console.log(arr.push(4, 5)); // 5
console.log(arr); // [1, 2, 3, 4, 5]

弹出元素 pop/shift

返回值:弹出数组的最后/第一个元素

var arr = [1,2,3];
​
console.log(arr.pop()); // 3
console.log(arr); // [1, 2]console.log(arr.shit()); // 1
console.log(arr); // [2]

数组元素排序 reverse/sort

返回值:翻转/排序的数组

reverse 翻转数组排序

var arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]
​
var pets = ['cat', 'dog', 'rabbit'];
pets.reverse();
console.log(pets); // ['rabbit', 'dog', 'cat']

sort(callback) 排序

  1. 按照元素 ASCII 码, 十进制的值来排序
  2. 默认是升序排序(假设元素全部是number类型)
  3. 如果想指定倒序排序, 可以传入一个检测函数
    1. 这个函数有二个参数 a, b
    2. 必须 return 一个number类型的值
    3. 如果return的值是负数, a 就排在 b 前面
    4. 如果return的值是正数, b 就排在 a 前面
    5. 如果return的值是 0, 则顺序保持不懂
var arr = [28, 36, 5, 6, 8];
​
arr.sort(); // 默认根据 ASCII 码排序
console.log(arr); // 结果并不是我们想要的效果: [28, 36, 5, 6, 8]
​
arr.sort(function(a, b) {
    if (a > b) {
    return -1; // 如果return的值是负数, a 就排在 b 前面
  } else {
    return 1; // 如果return的值是正数, b 就排在 a 前面
  }
});

替换数组元素 splice

返回值:被剪切的值

splice(start, deleteCount?, ...items?) :剪切或者替换数组现有的元素, 返回被剪切的值, 改变原数组

var arr = ["a", "b", "c", "d", "e"];
​
// 1. 从下标值为 start 的位置开始剪切, 如果没有后面两个参数, 则默认剪切到最后
console.log(arr.splice(2)); // 从开始位置截取到最后: ['c', 'd', 'e']
console.info(arr); // ['a', 'b']
​
​
// 2. 剪切 deleteCont 个元素, 如果没有 items 参数, 则直接返回被剪切的元素
arr = ["a", "b", "c", "d", "e"];
console.log(arr.splice(2, 2)); // 从开始位置截取2个: ['c', 'd']
console.info(arr); // ['a', 'b', 'e']
​
​
// 3. 剪切 deleteCount 个元素, 如果有 items 参数, 则用items参数替换(从start开始替换), 然后返回被剪切的元素
arr = ["a", "b", "c", "d", "e"];
console.info(arr.splice(2, 2, 1, 2, 3)); // 从开始位置, 截取一个, 然后替换成 1,2,3
console.info(arr); // ['a', 'b', 1, 2, 3, 'e']

Array 原型上的方法(不改变原数组)

合并数组:concat

返回值:合并后的新数组

合并两个数组, 并且返回合并后的新数组

var arr1 = [1, 3, 5];
var arr2 = [2, 4, 6];
var arr3 = arr1.concat(arr2);
​
console.log(arr1); // [1, 3, 5]
console.log(arr2); // [2, 4, 6]
console.log(arr3); // [1, 3, 5, 2, 4, 6]

截取数组元素:slice

返回值:截取后的元素

slice(start, end):截取数组中某个位置的元素,并返回截取的元素

  1. start: 从哪个下标开始截取,如果是负数则从后往前截取, 如果没有 end 参数, 则截取到最后
  2. end: 截取到那个下标, 但是不包括这个下标
var arr1 = ['a', 'b', 'c', 'd', 'e'];
​
console.log( arr1.slice(3) ); // ['d', 'e'], 从开始位置开始截取到最后
​
console.log( arr1.slice(1, 3) ); // ['b', 'c'], 结果没有包含下标为3的元素(不包括3)
​
console.log( arr1.slice(-3) ); // ['c', 'd', 'e'], 从-3开始截取到最后
​
console.log( arr1.slice(-4, 3) ); // ['b', 'c'], 从-4位置开始截取到索引为3的位置(不包括3)
​
console.log( arr1.slice(-4, -2) ); // ['b', 'c'], 从-4位置开始截取到索引为-2的位置(不包括-2)

字符串与数组互转:join/split

返回值:字符串/数组

// 数组 -> 字符串
var arr = ['a', 'b', 'c', 'd'];
var str = arr.join('-');
console.log(str); // a-b-c-d
​
// 字符串 -> 数组
var str = "a-b-c-d";
var arr = str.split('-');
console.log(arr); // ['a', 'b', 'c', 'd'];
​
// split 第二个参数: 限制返回的数组长度
var str = "a-b-c-d";
var arr = str.split('-', 2);
console.log(arr); // ['a', 'b']

类数组

什么是类数组?

  1. 是一个类似于数组对象, key的是索引值, 并且有 length 属性
  2. 没有 Array 构造函数原型对象上的方法
  3. arguments对象就是一个典型的类数组对象 Array-Like
// 以下就是一个类数组
var arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: '3'
};
​
// arguments 对象也是一个类数组// document.querySelectAll 返回的也是一个类数组
document.querySelectAll('div');