JS淬炼: Array进阶
在Javascript中,array是一个类数组的object。顾名思义,它能够在一个变量上存储多个值。
数组是值的有序集合。每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引。JavaScript数组是无类型:数组元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类型。 --《JavaScript权威指南(第六版)》
array在一般Javascript object基础上,有自己额外的属性。它采用numbered index作为的key,有一个length
property跟踪数组长度,还有如push/pop
、shift/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进阶相关推荐
- Js中Array对象
Js中Array对象 JavaScript的Array对象是用于构造数组的全局对象,数组是类似于列表的高阶对象. 描述 在JavaScript中通常可以使用Array构造器与字面量的方式创建数组. c ...
- 算法:js 数组 array 去重,并显示所有重复的元素
算法:js 数组 array 去重,并显示所有重复的元素 遇到这样一个问题,一个数组中查重并提取所有重复的项目,不仅仅只展示多出来的. [1,2,2,3,4,5,6,7,3,2,3] 得出 [2,2, ...
- 《前端防坑》- JS基础 - Array.isArray()结果一定准确吗?
在研究伪数组的时候发现了一个小问题,记录下,就是Array.isArray()判断数组的方法可能与instanceof判断出的结果可能不同. 参考文章:https://www.jianshu.com/ ...
- 【数组方法大合集】原生js数组array常用工具方法大合集
var array = {/* 数组求和*/sum: arr => eval(arr.join("+")),/* 判断一个数组(支持一个字符串)里面的是否有任何一个元素被包含 ...
- js javaScript array 取指定元素索引、判断是否相同、重复、过滤数据
最近写js也多了,Array中有好多方法不够用.自己加了些以后还可能用到. <script type="text/javascript"> //找到返回所在索引,不存在 ...
- 【JavaScript】JS的Array的用法总结
目录 Array的长度相关问题 indexOf取元素下标 slice操作 push和pop操作 unshift和shift操作 sort操作 reverse操作 spilce操作 concat函数 j ...
- 2020-08-04 html的js位置 + css的flex实现九宫格 + JS的Array + 软技能的硬编码
2020-08-04 题目来源:http://www.h-camel.com/index.html [html] 一般习惯把js写在</body>前,但有例外的情况吗?说说看 html文件 ...
- JavaScript -- Array进阶详解
如没有特别说明,测试宿主环境为Node.js 文章目录 前言 一.逗号创建数组 二.容易忽略的.length 三.检测数组的两种方法 四.迭代器方法(返回迭代器) 五.迭代方法(返回boolean值或 ...
- js中Array数组中的常用方法汇总
Array的push与unshift方法性能比较分析 从原理就可以知道,unshift的效率是较低的.原因是,它每添加一个元素,都要把现有元素往下移一个位置.unshift比push要慢差不多100倍 ...
最新文章
- 如何找到foreach索引
- WP8.1 Study18:动态磁贴
- Boost:分配服务的实例
- 转载:pycharm最新版新建工程没导入本地包问题:module 'selenium.webdriver' has no attribute 'Firefox'...
- 腾讯专利多大吓人,专利之王,一点都不过分
- Java成神之路——String长度限制
- 盘点 | 2017 年关于 Python 的 12 件大事
- GridView中使用DropDownList的OnSelectedIndexChanged事件
- mysql书单推荐_MySQL有什么推荐的学习书籍
- 学习记录:小程序图片上传至服务器
- 项目管理手记(七)--DRP系统的文化输出与营销
- (Java)L1-039 古风排版
- 联想微型计算机c325参数,联想一体机c325性能表现 联想一体机c325配置参数
- 第三届厦门国际银行数创金融杯金融营销建模大赛-BaseLine
- 新上线的“闪电”算法
- S32K14x CAN休眠唤醒的实现方案
- SOLIDWORKS快捷键167个小技巧
- 基于遗传算法优化的BP神经网络算法
- 我从未见过一个早起、勤奋、谨慎、诚实的人抱怨命运不好
- 计算机常见故障ppt,计算机硬件组成与常见故障排错.ppt
热门文章
- 计算机网络与安全实践课程设计-实验室局域网建设方案,实验室局域网建设方案.doc...
- Oracle添加修改删除字段操作与注意事项
- 在Carla模拟地图中定位到特定位置并创建汽车
- BIN文件通过ST-LINK烧录STM32芯片(转)
- 软件工程第五次作业—个人总结
- 如何在另一个城市找到工作
- 写定时任务发送邮件报错(Could not connect to SMTP host:smtp.exmail.qq.com,port:465)
- js获取图片的EXIF,解决图片旋转问题
- springmvc 整合 camunda
- 适合零基础的Java基础入门知识(部分,后续会不断更新)-看后觉得不错,请点赞收藏-咱们一起进步