Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 数组 #13

Closed
Checkson opened this issue Feb 16, 2019 · 0 comments
Closed

JavaScript 数组 #13

Checkson opened this issue Feb 16, 2019 · 0 comments

Comments

@Checkson
Copy link
Owner

Checkson commented Feb 16, 2019

简介

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

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。这两个参数有什么用呢?上面罗列了三点对这两个参数的用法,用我的话形容则是:

字符串类型:

  • 返回a < b ? -1 : a === b ? 0 : 1,从小到大排序
  • 返回b < a ? -1 : a === b ? 0 : 1,从大到小排序

数字类型:

  • 返回a - b,从小到大排序
  • 返回b - a,从大到小排序

请看代码示例:

字符串类型排序:

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:我只负责帮大家对知识点扫盲,并不会展开一些对数组基础东西的讲解。

@Checkson Checkson closed this as completed Oct 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant