Array构造器

如果参数只有一个并且是Number类型,那么就是指定数组的长度,但不能是NaN,如果是多个会被当做参数列表。

new Array(12)
// (12) [undefined × 12]
new Array('')
// [""]
new Array({})
// [Object]
new Array([])
// [Array(0)]
new Array(null)
// [null]
new Array(NaN)
// Uncaught RangeError: Invalid array length (无效的数组长度,因为NaN是Number类型,但又不是一个具体的数字因此报错)

注意当只传递一个参数时,它只是指定该数组的长度,并不会去填充内容

由于传递一个参数时不会填充数组内容,因此forEach不会循环这些空内容,或者说forEach不是根据数组长度来循环的,以下代码就不会被输出任何内容

new Array(6).forEach(function(item,index){
console.log(index)
});

像我们自己模拟的forEach基本上都是有问题的,因为我看大部分人都是通过for循环数组的长度来模拟的forEach

function forEach(arr,fun){
for(var i = 0; i < arr.length; i++){
fun(arr[i]);
}
}

这就说明在某些情况下数组的长度是不可靠的,并且我们没有办法去真实的模拟forEach,通过判断是不是undefined也是不准确的。

由于传递一个参数时只会增加数组长度而不会填充内容,因此我们可以利用这个特点来实现自定义索引起始位置。

new Array(10).concat([1,2,3,4,5]).forEach(function(item,index){
console.log(`item: ${item} index: ${index}`);
});
// item: 1 index: 10
// item: 2 index: 11
// item: 3 index: 12
// item: 4 index: 13
// item: 5 index: 14

当然我们也可以这样玩

new Array(10).concat([1,2,3,4,5]).concat(new Array(5)).concat([6,7,8,9,10])

这种方式有个好处就是,空内容不会被循环到。

它还可以用来实现相同的连续字符

new Array(5+1).join("哈") //由于数组索引是从0开始的所以需要加+1才是5
// "哈哈哈哈哈"

我们用它来输出一个好玩的

new Array(3).concat(['l','o','v','e']).concat(new Array(3)).join('--')
// "------l--o--v--e------"

如果你希望设置默认填充内容可以使用数组的fill方法

new Array(5).fill(999)
[999, 999, 999, 999, 999]

我们也可以使用下面这种方式来实现默认填充内容

var arr = new Array(5).join('5,').split(',');
arr.splice(-1,1);
// ["5", "5", "5", "5"]

以上这种方式的缺点就是都会变成字符串。

通过Array()方法来创建数组和用new方法来创建效果一样。

数组的访问

数组通过下标访问

[2,3,4,5][1]
// 3

当我们通过以下方式进行访问时,会被解析成连续运算返回最后一个值

[2,3,4,5][1,2]
// 4

由于以上[1,2]是去访问数组的下标因而被解析成了1,2结果返回的是2,所以以上输出4

数组也是一种特殊的对象,因此我们也可以通过键值对的形式去访问

var arr = [];
arr.say = 'Hello';
arr.say
// "Hello"

数组与其他值的运算

数组和任何值相加都会将数组转换成字符串再进行拼接

[1,2,3] + 6
// "1,2,36"
[1,2,3] + {}
// "1,2,3[object Object]"
[1,2,3] + [1,2,3]
// "1,2,31,2,3"

如果数组只有一个值,那么当这个数组和其他值相减相乘等时会被转换为数字,如果为空会被转换为0

[5] - 2
// 3

如果是多个值,肯定是NaN

遍历数组

使用for

var arr = [2,3,4,5];
for(let i = 0, len = arr.length; i < len; i++){
console.log(arr[i])
}
// 2
// 3
// 4
// 5

使用forEach

var arr = [2,3,4,5];
arr.forEach((item)=>console.log(item))
// 2
// 3
// 4
// 5

使用map、filter、some等方法都可以达到遍历数组的目的,不过这些方法都不能直接通过return来跳出循环,但我们可以通过以下方式来实现跳出循环

var arr = [2,3];
try{
arr.forEach(function(item){
if(item === 3){
throw Error();
}
console.log(item);
});
}catch(e){
}
// 2

使用for in

var arr = [2,3];
for(let k in arr){
console.log(arr[k]);
}
// 2
// 3

不过由于for in会将继承的属性和方法也遍历出来,如下所示

Array.prototype.a = 123;
Array.prototype.foo = function(){};
var arr = [2,3];
for(let k in arr){
console.log(arr[k]);
}
// 2
// 3
// 123
// function (){}

所以我们还得过滤一下

Array.prototype.a = 123;
Array.prototype.foo = function(){};
var arr = [2,3];
for(let k in arr){
if(arr.hasOwnProperty(k)){
console.log(arr[k]);
}
}
// 2
// 3

我们还可以使用for of来实现同样的效果,并且没有以上问题

var arr = [2,3];
for(let item of arr){
console.log(item)
}
// 2
// 3

有时我们并不希望一次性遍历所有的数组项,而是根据需求来执行,此时我们就需要用到迭代器了,数组中有一个keys方法可以生成一个迭代器,如下

var arr = [2,3];
var iterator = arr.keys();
console.log(iterator.next().value);
console.log('-----');
console.log(iterator.next().value); // 0
// -----
// 1

返回的是索引 Array.prototype.keys

其他

实际上JavaScript中的数组并非是传统意义上的数组,而是一个关联数组,索引数组只是个表面现象,我们通过下标的方式去访问数组,它最终还是会被转换为字符串的。

[2,3][1]
// 3

其实它是这样

[2,3]["1"]
// 3

如果说javascript中的数组不是索引数组而是关联数组,那么我们在使用for循环时为什么可以按照顺序来输出呢?

var arr = [2,3];
for(var i = 0, len = arr.length; i < len; i++){
console.log(arr[i]);
}
// 2
// 3

如果我们仔细观察以上代码,会发现一个啃爹的现象,我们被欺骗了很久,我们是用0 1 2这样的形式去访问的数组,自然是按照顺序输出了,再看看下面这段代码,估计你就懂了

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

你可是手动去访问人家某个具体属性的,你说能不是按照顺序输出吗。

这也就是为什么数组可以使用for in方法来循环的原因,因为本质上来讲数组具有对象的某些特性,也就说其实我们也可以自己用对象来模拟实现数组,不过我们需要手动去维护length属性,从另外一个角度上来讲JavaScript中的数组很大一部分只是维护了length属性,跟对象没什么两样。

走进javascript——数组的那些事的更多相关文章

  1. 关于javascript removeChild的那些事

    关于javascript removeChild的那些事 今天给removeChild搞死了,弄了几个小时,上代码 <ul id="myList"> <li> ...

  2. 从JavaScript 数组去重看兼容性有关问题,及性能优化(摘自玉伯博客)

    JavaScript 数组去重经常出现在前端招聘的笔试题里,比如: 有数组 var arr = ['a', 'b', 'c', '1', 0, 'c', 1, '', 1, 0],请用 JavaScr ...

  3. Javascript数组操作

    使用JS也算有段时日,然对于数组的使用,总局限于很初级水平,且每每使用总要查下API,或者写个小Demo测试下才算放心,一来二去,浪费不少时间:思虑下,堪能如此继续之?当狠心深学下方是正道. 原文链接 ...

  4. Javascript数组操作(转)

    1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...

  5. JavaScript 数组

    JavaScript 数组 简介:数组是值的有序集合,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. 一:创建数组 ...

  6. 也谈面试必备问题之 JavaScript 数组去重

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  7. js 判断数组包含某值的方法 和 javascript数组扩展indexOf()方法

    var  questionId = []; var anSwerIdValue = []; ////javascript数组扩展indexOf()方法 Array.prototype.indexOf ...

  8. JavaScript 数组 length 属性获取数组长度或设置数组元素的数目

    JavaScript 数组 length 属性 JavaScript 数组 length 属性可返回或设置或组中元素的数目,语法如下: array_object.length 利用 length 属性 ...

  9. 【读书笔记】-- JavaScript数组

    数组是一段线性分配的内存,它通过整数计算偏移并访问其中的元素.大多数的语言都会要求一个数组的元素是相同类型,但JavaScript数组可以包含任意类型. var misc = ['string', n ...

随机推荐

  1. Linux之环境变量

    1. 变量的显示与设置 显示变量 echo \(PATH</font></code><br/> 取消变量 <code><font color=&q ...

  2. 简单分析下用yii2的yii\helpers\Html类和yii.js实现的post请求

    yii2提供了很多帮助类,比如Html.Url.Json等,可以很方便的实现一些功能,下面简单说下这个Html.用yii2写view时时经常会用到它,今天在改写一个页面时又用到了它.它比较好用的地方就 ...

  3. Java中log4j的使用

    前言 距离上一篇文章又过去好长时间了,这段时间一直忙于工作,已经从net彻底转向Java了.工作也慢慢的步入正轨了,自己独自完成了一个小项目,不过工作中遇到了一些问题,还是得到了同学和同事的帮助.本来 ...

  4. Linux上常用的文件传输方式以及比较

    tp ftp 命令使用文件传输协议(File Transfer Protocol, FTP)在本地主机和远程主机之间或者在两个远程主机之间进行文件传输. FTP 协议允许数据在不同文件系统的主机之间传 ...

  5. 【模板】链式前向星+spfa

    洛谷传送门--分糖果 博客--链式前向星 团队中一道题,数据很大,只能用链式前向星存储,spfa求单源最短路. 可做模板. #include <cstdio> #include <q ...

  6. Android 代码库(自定义一套 Dialog通用提示框 )

          做Android开发五年了,期间做做停停(去做后台开发,服务器管理),当回来做Android的时候,发现很生疏,好些控件以前写得很顺手,现在好像忘记些什么了,总要打开这个项目,打开那个项目 ...

  7. CSAcademy Beta Round #4 Swap Pairing

    题目链接:https://csacademy.com/contest/arhiva/#task/swap_pairing/ 大意是给2*n个包含n种数字,每种数字出现恰好2次的数列,每一步操作可以交换 ...

  8. java获得路径的多种方式

    本文讲解java语言中获得运行时路径的多种方式,包括java项目.java web项目.jar.weblogic等多种场景. 一.this.getClass().getClassLoader().ge ...

  9. Java使用POI为Excel打水印,调整列宽并设置Excel只读(用户不可编辑)

    本文介绍在Java语言环境下,使用POI为Excel打水印的解决方案,具体的代码编写以及相关的注意事项. 需求描述: 要求通过系统下载的Excel都带上公司的水印,列宽调整为合适的宽度,并且设置为不可 ...

  10. bzoj2144 【国家集训队2011】跳跳棋

    Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...