在Javascript中,array是一个类数组的object。顾名思义,它能够在一个变量上存储多个值。

数组是值的有序集合。每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引。JavaScript数组是无类型:数组元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类型。 --《JavaScript权威指南(第六版)》

array在一般Javascript object基础上,有自己额外的属性。它采用numbered index作为的key,有一个length property跟踪数组长度,还有如push/popshift/unshift等数组特有操作。

本质是object

作为一个object,我们可以在array上面进行所有object的合法操作,比如设置一个named key。

var test = [];
test.fruit = "APPLE";
console.log(test.fruit); // APPLE

上面仅仅把array作为一个普通的Javascript object使用,等价于var test = {}。在这种场合,我们应该选择普通的Javascirpt object,而非array。

Numbered index

Javascript中的 array object 采用了一个很朴素的思想来实现数组 —— 用数字来充当object的keys。这样在表面上延续了我们在C++/Java上使用数组的编程体验。

{ 0 : item0, 1 : item1, 2 : item2
}

array的这种实现方式导致了一些尴尬问题,比如删除元素、元素遍历。我们会在后面谈到这些问题。

删除元素

delete operator(不推荐)

和一般Javascript object一样,我们可以使用delete来删除object中的property。

var arr = ['a', 'b', 'c', 'd'];
delete arr[1];
console.log(arr);
console.log(arr[1]);
// [ 'a', , 'c', 'd' ]
// undefined

当我们使用delete来删除某一个元素arr[1]时,arr中key 1 和value b之间的连接被切断,key 1对应的值被重置为undefined。注意,这时候,array中其他元素并没有改变自身的index来填补这key 1这个空洞,而是保持原值。这样,key 1就变成了arr中的一个洞了!

除非有特殊需求,比如需要用到sparse array,一般情况下并不推荐使用delete operator来删除array中的元素。

splice() (推荐)

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1); // Removes the first element of fruits

第一个参数 (0) 定义新元素要从哪个位置插入。第二个参数 (1) 定义新元素插入位置开始有多少元素要被删除。后面的参数被忽略掉了,表示并没有要插入的元素。

filter()(推荐)

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var toDelete = "Apple";
fruits = fruits.filter(function(value) { return value != toDelete;
});
// [ 'Banana', 'Orange', 'Mango' ]

理解length

length是array object的一个property, 根据名字来看,似乎是记录array的长度。其实,length的本质是跟踪array中的max_index,并始终保持值是max_index + 1

这和记录长度有什么区别呢?

还记得使用delete来删除元素的情形吧?中间元素被删了,但是其他元素没有改变自身的index来填补空间。这时候即使delete了多个元素,数组的length可能并没有发生变化。

var array_object = [1, 2, 3];
console.log(array_object.length); // 3
delete array_object[1];
console.log(array_object.length); // 3!

Array 遍历

如果array中没有“洞”, for loop和forEach两种遍历方式区别不大。在array有洞的情况下,两者略有不同,其中forEach会跳过这些洞,而传统的for loop并不会。

var array_object = [1, 2, 3];
delete array_object[1];// 不跳过洞
for(var i=0; i<array_object.length; i++) {     console.log(array_object[i]);
};
//1 undefined 3//跳过洞
array_object.forEach(function(s) { console.log(s);
});
// 1 3

遍历array的方法还有其他,更多方法可以参考这篇StackOverflow问答。

[] vs. new Array( )

当新建一个array时候,我们有下面两种方式: array literal [] 或 array constructor new Array(arg)

var arrayA = [];
var arrayB = new Array();

当使用[]时候, JS engine会直接调用global Array的constructor新建一个array变量并返回。当使用new Array()时候, JS engine会沿着Execution Context往上追溯到名为Array的constructor function,并据此生成一个object。这时候,虽然不大可能,Array可能会在中间某个Execution Context中被用户重新定义。下面是coderjoe在StackOverflow中提出的例子。在例子中,我们最后得到的并不是我们期待的原生Array。

function Array() { this.is = 'SPARTA';
}
var a = new Array();
var b = [];
alert(a.is);
// => 'SPARTA'
alert(b.is);
// => undefineda.push('Woa');
// => TypeError: a.push is not a functionb.push('Woa');
// => 1 (OK)

大部分Javascirpt社区推荐使用[]来新建array。

You never need to use new Object() in JavaScript. Use the object literal {} instead. Similarly, don’t use new Array(), use the array literal [] instead. Arrays in JavaScript work nothing like the arrays in Java, and use of the Java-like syntax will confuse you. LINK

Array 复制

浅度复制

var arr1 = ['a', 'b', 'c'];
var arr2 = arr1;
arr2[0] = 1; // 对数组arr2的元素进行修改
console.log(arr1); // [1, 'b', 'c']

深度复制

var arr1 = ['a', 'b', 'c', 'd', 'e'];
var arr2 = arr1.concat(); // 使用concat()方法,返回新的数组
arr2[0] = 1;
console.log(arr1); // => ['a', 'b', 'c', 'd', 'e']:数组arr1的元素没变更
console.log(arr2); // => [ 1, 'b', 'c', 'd', 'e']:数组arr2的元素发生了变更

Associate Array

在计算机科学中,采用named index而非numbered index的数组被称为Associative Array。

var associative_array = new Array();
associative_array["one"] = "Lorem";
associative_array["two"] = "Ipsum";
associative_array["three"] = "dolor";for (i in associative_array) { console.log(i);
};
// one two three 

上面操作可以应用在任何Javascript object上,array object也不例外。但是在Javascript array上进行这种操作是很糟糕的。当需要使用named string作为key时候,我们应该使用一般的object,而非array。

Javascript里面并不支持named index的array。

If you use a named index, JavaScript will redefine the array to a standard object. After that, all array methods and properties will produce incorrect results... In JavaScript, arrays always use numbered indexes. LINK

Reference

  • Iterating over an array with “holes” in JavaScript

  • Create an empty object in JavaScript with {} or new Object()?

  • What’s the difference between “Array and “[]” while declaring a JavaScript array?

  • JavaScript Array对象

JS淬炼: Array进阶相关推荐

  1. Js中Array对象

    Js中Array对象 JavaScript的Array对象是用于构造数组的全局对象,数组是类似于列表的高阶对象. 描述 在JavaScript中通常可以使用Array构造器与字面量的方式创建数组. c ...

  2. 算法:js 数组 array 去重,并显示所有重复的元素

    算法:js 数组 array 去重,并显示所有重复的元素 遇到这样一个问题,一个数组中查重并提取所有重复的项目,不仅仅只展示多出来的. [1,2,2,3,4,5,6,7,3,2,3] 得出 [2,2, ...

  3. 《前端防坑》- JS基础 - Array.isArray()结果一定准确吗?

    在研究伪数组的时候发现了一个小问题,记录下,就是Array.isArray()判断数组的方法可能与instanceof判断出的结果可能不同. 参考文章:https://www.jianshu.com/ ...

  4. 【数组方法大合集】原生js数组array常用工具方法大合集

    var array = {/* 数组求和*/sum: arr => eval(arr.join("+")),/* 判断一个数组(支持一个字符串)里面的是否有任何一个元素被包含 ...

  5. js javaScript array 取指定元素索引、判断是否相同、重复、过滤数据

    最近写js也多了,Array中有好多方法不够用.自己加了些以后还可能用到. <script type="text/javascript"> //找到返回所在索引,不存在 ...

  6. 【JavaScript】JS的Array的用法总结

    目录 Array的长度相关问题 indexOf取元素下标 slice操作 push和pop操作 unshift和shift操作 sort操作 reverse操作 spilce操作 concat函数 j ...

  7. 2020-08-04 html的js位置 + css的flex实现九宫格 + JS的Array + 软技能的硬编码

    2020-08-04 题目来源:http://www.h-camel.com/index.html [html] 一般习惯把js写在</body>前,但有例外的情况吗?说说看 html文件 ...

  8. JavaScript -- Array进阶详解

    如没有特别说明,测试宿主环境为Node.js 文章目录 前言 一.逗号创建数组 二.容易忽略的.length 三.检测数组的两种方法 四.迭代器方法(返回迭代器) 五.迭代方法(返回boolean值或 ...

  9. js中Array数组中的常用方法汇总

    Array的push与unshift方法性能比较分析 从原理就可以知道,unshift的效率是较低的.原因是,它每添加一个元素,都要把现有元素往下移一个位置.unshift比push要慢差不多100倍 ...

最新文章

  1. 如何找到foreach索引
  2. WP8.1 Study18:动态磁贴
  3. Boost:分配服务的实例
  4. 转载:pycharm最新版新建工程没导入本地包问题:module 'selenium.webdriver' has no attribute 'Firefox'...
  5. 腾讯专利多大吓人,专利之王,一点都不过分
  6. Java成神之路——String长度限制
  7. 盘点 | 2017 年关于 Python 的 12 件大事
  8. GridView中使用DropDownList的OnSelectedIndexChanged事件
  9. mysql书单推荐_MySQL有什么推荐的学习书籍
  10. 学习记录:小程序图片上传至服务器
  11. 项目管理手记(七)--DRP系统的文化输出与营销
  12. (Java)L1-039 古风排版
  13. 联想微型计算机c325参数,联想一体机c325性能表现 联想一体机c325配置参数
  14. 第三届厦门国际银行数创金融杯金融营销建模大赛-BaseLine
  15. 新上线的“闪电”算法
  16. S32K14x CAN休眠唤醒的实现方案
  17. SOLIDWORKS快捷键167个小技巧
  18. 基于遗传算法优化的BP神经网络算法
  19. 我从未见过一个早起、勤奋、谨慎、诚实的人抱怨命运不好
  20. 计算机常见故障ppt,计算机硬件组成与常见故障排错.ppt

热门文章

  1. 计算机网络与安全实践课程设计-实验室局域网建设方案,实验室局域网建设方案.doc...
  2. Oracle添加修改删除字段操作与注意事项
  3. 在Carla模拟地图中定位到特定位置并创建汽车
  4. BIN文件通过ST-LINK烧录STM32芯片(转)
  5. 软件工程第五次作业—个人总结
  6. 如何在另一个城市找到工作
  7. 写定时任务发送邮件报错(Could not connect to SMTP host:smtp.exmail.qq.com,port:465)
  8. js获取图片的EXIF,解决图片旋转问题
  9. springmvc 整合 camunda
  10. 适合零基础的Java基础入门知识(部分,后续会不断更新)-看后觉得不错,请点赞收藏-咱们一起进步