数组是一段线性分配的内存, 它通过整数计算偏移并访问其中的元素. 数组是一种性能出色的数据结构.
1. 数组字面量
数组字面量提供了一种非常方便地创建新数组的表示法. 多个用逗号分隔的值的表达式. 数组字面量允许出现在任何表达式可以出现的地方. 数组的第一个值将获得属性名'0', 第二个值将获得属性名'1', 以此类推:
- var empty = [];
- var numbers = [
- 'zero', 'one', 'two', 'three', 'four',
- 'five', 'six', 'seven', 'eight', 'nine'
- ];
- console.log(empty[1]); // undefined
- console.log(numbers[1]);// 'one'
- console.log(empty.length);// 0
- console.log(numbers.length);// 10
对象字面量:
- var numbers_object = {
- '0': 'zero',
- '1': 'one',
- '2': 'two',
- '3': 'three',
- '4': 'four',
- '5': 'five',
- '6': 'six',
- '7': 'serven',
- '8': 'eight',
- '9': 'nine'
- };
两者产生的结果相似, numbers 和 numbers_object 都是包含 10 个属性的对象, 并且那些属性刚好有相同的名字和值. 但是他们也有一些显著的不同, numbers 继承自 Array.prototype, 而 numbers_object 继承自 Object.prototype, 所以 numbers 继承了大量有用的方法. 同时, numbers 也有一个诡异的 length 属性, 而 numbers_object 则没有.
在大多数语言中, 一个数组所有元素都要求是相同的类型. JavaScript 允许数组里包含任意混合类型的值:
- var misc = [
- 'string', 98.6, true, false, null, undefined,
- ['nested', 'array'], {object: true}, NaN,
- Infinity
- ];
- console.log(misc.length);// 10
在 JavaScript 中, 中括号 [] 表示一个数组, 也可以理解为数组对象; 花括号 {} 表示一个对象, []和 {} 一起使用, 可以形成一个对象数组, 如以上示例所示.
2. 长度
每个数字都有一个 length 属性, 和大多数其他语言不同, JavaScript 数组的 length 是没有上界的. 如果你用大于或等于当前 length 的数字作为下标来存储一个元素, 那么 length 值会被增大以容纳新元素, 不会发生数组越界错误.
length 属性的值是这个数组的最大整数属性名加上 1, 它不一定等于数组里的属性的个数:
- var myArray = [];
- console.log(myArray.length);// 0
- myArray[1000000] = true;
- console.log(myArray.length);// 10000001
- // myArray 只包含一个属性
[]后置下标运算符把它所含的表达式转换成一个字符串, 如果该表达式有 toString 方法, 就使用该方法的值. 这个字符串被将用作属性名. 如果这个字符串看起来像一个大于等于这个这个数组当前的 length 且小于 4294967295 的正整数, 那么这个数组的 length 会被重新设置为新的下标加 1, 否则 length 值为这个数组的长度.
3. 删除
由于 JavaScript 的数组其实就是对象, 所以 delete 运算符可以用来从数组中移除元素:
- var numbers = ['zero', 'noe', undefined, 'shi', 'go'];
- delete numbers[2];
- console.log(numbers.length);// 5
不幸的是, 那样会在数组中留下一个空间. 这是因为排在被删除元素之后的元素保留着它们最初的属性. 而你通常想要的是递减后面每个元素的属性.
幸运的是, JavaScript 数组有一个 splice 方法. 它可以对数组做个手术, 删除一些元素并将它们替换为其他的元素. 第 1 个参数是数组中的一个序号, 第 2 个参数是要删除的元素个数. 任何额外的参数会在序号那个点的位置被插入到数组中:
- var numbers = ['zero', 'noe', undefined, 'shi', 'go'];
- numbers.splice(2, 1);
- console.log(numbers.length);// 4
值为'shi'的属性的键值从'3'变到'2'. 因为被删除属性后面的每个属性必须被移除, 并且以一个新的键值重新插入, 这对于大型数组来说可能会效率不高.
4. 容易混淆的地方
在 JavaScript 编程中, 一个常见的错误是在必须使用数组时使用了对象, 或者在必须使用对象时使用了数组. 其实规则很简单: 当属性名是小而连续的整数时, 你应该使用数组. 否则, 使用对象.
JavaScript 本身对于数组和对象的区别是混乱的. typeof 运算符报告数组的类型是'object', 这没有任何意义, JavaScript 没有一个好的机制来区别数组和对象, 我们可以通过定义自己的 is_array 函数来弥补这个缺陷:
- var array = [
- 'zero', 'one'
- ];
- var obj = {
- '0': 'zero',
- '1': 'one'
- };
- var is_array = function (value) {
- return Object.prototype.toString.apply(value) === '[object Array]';
- };
- console.log(is_array(array));// true
- console.log(is_array(obj));// false
5. 方法
JavaScript 提供了一套数组可用的方法. 这些方法是被储存在 Array.prototype 中的函数, Object.prototype 和 Array.prototype 是可以被扩充的, 举例来说, 假设我们想要给 array 增加一个方法, 它允许我们队数组进行计算:
- // 通过给 Function.prototype 增加方法来使得该方法对所有函数可用
- Function.prototype.method = function (name, func) {
- this.prototype[name] = func;
- return this;
- };
- Array.method('reduce', function (f, value) {
- var i;
- for (i = 0; i < this.length; i++) {
- value = f(this[i], value);
- }
- return value;
- });
通过给 Array.prototype 扩充了一个函数, 每个数组都继承了这个方法. 在这个例子里, 我们定义了一个 reduce 方法, 它接受一个函数和一个初始值作为参数,. 它便利这个数组, 以当前元素和该初始值为参数调用这个函数, 并且计算出一个新值. 当完成时, 它返回这个新值.
如果我们传入一个把两个数字相加的函数, 它会计算出相加的和. 如果我们传入把两个数组相乘的函数, 它会计算两者的乘积:
- // 创建一个数组数组
- var data = [4, 8, 15, 16, 23, 42];
- // 定义两个简单的函数, 一个是把两个数字相加, 另一个是把两个数字相乘.
- var add = function (a, b) {
- return a + b;
- };
- var mult = function (a, b) {
- return a * b;
- };
- // 调用 data 的 reduce 方法, 传入 add 函数.
- var sum = data.reduce(add, 0);
- console.log(sum);// 108
- // 再次调用 reduce 方法, 这次传入 mult 函数
- var product = data.reduce(mult, 1);
- console.log(product);// 7418880
- // 因为数组其实就是对象, 所以我们可以直接给一个单独的数组添加方法:
- data.total = function () {
- return this.reduce(add, 0);
- };
- console.log(data.total());// 108
6. 指定初始值
JavaScript 的数组通常不会预置值. 如果你用 [] 得到一个新数组, 它将是空的. 如果你访问一个不存在的元素, 得到的值则是 undefined. 如果你知道这个问题, 或者你在尝试获取每个元素之前都很有预见性地设置他的值, 那就万事大吉了. 但是, 如果你实现的算法是假设每个元素都从一个已知的值开始(例如 0), 那么你必须自己准备好这个数组. JavaScript 应该提供一些类似 Array.dim 这样的方法来做这件事情, 但我们可以很容易纠正这个疏忽:
- Array.dim = function (dimension, initial) {
- var a = [], i;
- for (i = 0; i < dimension; i++) {
- a[i] = initial;
- }
- return a;
- };
- // 创建一个包含 10 个 0 的数组
- var myArray = Array.dim(10, 0);
JavaScript 没有多维数组, 但就像大多数类 C 语言一样, 它支持元素为数组的数组:
- var matrix = [
- [0, 1, 2],
- [3, 4, 5],
- [6, 7, 8]
- ];
- console.log(matrix[2] [1]);// 7
JavaScript 对矩阵也提供了更好的支持:
- Array.matrix = function (m, n, initial) {
- var a, i, j, mat = [];
- for (i = 0; i < m; i++) {
- a = [];
- for (j = 0; j < n; j++) {
- a[j] = initial;
- }
- mat[i] = a;
- }
- return mat;
- };
- // 构造一个用 0 填充的 4 * 4 矩阵
- var myMatrix = Array.matrix(4, 4, 0);
- console.log(myMatrix);
- console.log(myMatrix[3] [3]);// 0
用 0 填充的 4 * 4 矩阵:
- // 用来构造一个单位矩阵的方法
- Array.identity = function (n) {
- var i, mat = Array.matrix(n, n, 0);
- for (i = 0; i < n; i++) {
- mat[i] [i] = 1;
- }
- return mat;
- };
- myMatrix = Array.identity(4);
- console.log(myMatrix);
- console.log(myMatrix[3] [3]);// 1
单位矩阵:
来源: https://www.cnblogs.com/dukeShi/p/8993326.html