Checkson / blog

Checkson个人博客
12 stars 3 forks source link

JavaScript 数组 #13

Closed Checkson closed 4 years ago

Checkson commented 5 years ago

简介

数组是计算机编程世界里最常见的数据结构。任何一种编程语言都包含数组,只是形式上略有不同罢了。数组是编程语言中的内建类型,通常效率很高,可以满足不同需求的数据存储。

JavaScript中对数组的定义

JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性,索引可能是整数。然而,这些数字索引在内部被转换为字符串类型,这是因为 JavaScript 对象中的属性名必须是字符串。数组在 JavaScript 中只是一种特殊的对象,所以效率上不如其他语言中的数组高。

JavaScript 中的数组,严格来说应该称作对象,是特殊的 JavaScript 对象,在内部被归类为数组。由于 Array 在 JavaScript 中被当作对象,因此它有许多属性和方法可以在编程时使用。

下面代码论证上述观点:

var arr = [1, 2, 3, 4, 5];
console.log(arr[1] === arr['1']); // true;
console.log(typeof arr); // object
var indexObj = { toString: function () { return 0; } }
console.log(arr[indexObj]); // 1

可见,数组在JavaScript内部也是object类型;数组根据索引获取元素的时候,会自动将下标转化为字符串。

数组创建

// 尽量使用字面量形式创建数组,因为它效率较高
var arr = [1, 2, 3, 4, 5];
// 构造函数创建数组
var arr = new Array(1, 2, 3, 4, 5);
// 通过字符串方法创建
var arr = '1,2,3,4,5'.split(',');

数组复制

var arr = [1, 2, 3, 4, 5];
var newArr = arr;
newArr[0] = 6;
console.log(arr[0]); // 6

这种方式把一个数组赋给另外一个数组时,只是为被赋值的数组增加了一个新的引用。我们称之为"浅拷贝",操作新的数组,会影响到旧的数组。对应的,我们也有”深拷贝“。

function deepCopy(src, dst) {
    for (var i = 0, len = src.length; i < len; i++) {
        dst[i] = src[i];
    }
}
var arr = [1, 2, 3, 4, 5];
var newArr = [];
deepCopy(arr, newArr);
newArr[0] = 6;
console.log(arr[0]); // 1

这个数组”深拷贝“操作并不完美,只针对数组元素中只有基本数据类型,若存在引用数据类型元素,则不适用。

数组方法

这里不展开,可以点击查看JavaScript Array 对象相关方法操作。

数组排序

定义:

arrayObject.sort(sortby); // sortby:可选。规定排序顺序。必须是函数。

这里重点讲解JavaScript中的数组排序,因为它很特别。例如我们要对一个字符串数组进行排序,可以这样写:

var arr = ['yes', 'or', 'no'];
arr.sort();
console.log(arr); // ['no', 'or', 'yes'];

看上去很简单的调用sort方法,就能轻松地实现数组的排序。那么,某一天我按字符串首字母从大到小排序呢?当然我们可以这样做:

var arr = ['yes', 'or', 'no'];
arr.sort().reverse();
console.log(arr); // ['yes', 'or', 'no'];

我能不能通过sort方法就一步到位呢?这时候,我们就要用上sort方法接受的参数sortby了。注意,sortby它代表的是一个函数的饮用,而不是一个boolean值。曾经天真的我以为sort(true) ,顺序排序;sort(false),逆序排序,然而并不是。我们看看官方对sortby的定义:

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。 若 a 等于 b,则返回 0。 若 a 大于 b,则返回一个大于 0 的值。

相信第一次读这个定义的同学也会和当初的我一样晕,没关系的,因为有我在。首先呢,这个sortby函数,是一个回调函数,就像我们平时事件绑定,ajax回调函数一样,在数组排序过程中调用,并且注入了两个参数ab。这两个参数有什么用呢?上面罗列了三点对这两个参数的用法,用我的话形容则是:

字符串类型:

数字类型:

请看代码示例:

字符串类型排序:

function asc (a, b) { return a < b ? -1 : a === b ? 0 : 1; }
function desc (a, b) { return b < a ? -1 : a === b ? 0 : 1; }
var arr = ['yes', 'or', 'no'];
arr.sort(asc);
console.log(arr); // ['no', 'or', 'yes']
arr.sort(desc);
console.log(arr); // ['yes', 'or', 'no']

数字类型排序:

function asc (a, b) { return a - b; }
function desc (a, b) { return b - a; }
var arr = [3, 1, 2];
arr.sort(asc);
console.log(arr); // [1, 2, 3]
arr.sort(desc);
console.log(arr); // [3, 2, 1]

如果好奇js数组中的原生sort方法是用什么排序算法的同学,可以点击这里查看。

ps:我只负责帮大家对知识点扫盲,并不会展开一些对数组基础东西的讲解。