在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念。那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记不清数组的大多数用法,只知道push,pop,shift等最基本的几个。所以,本系列(数组篇)会尽可能的让大家对数组有一个透彻的了解。也方便后面其他数据结构的学习和使用。

   可能很多web前端开发者都会有一个疑问,那就是,数组和对象究竟是数据类型?还是数据结构?那么我们就带着这样的疑问,开始下面的学习,希望看完这篇文章之后,你模糊的概念会变得清晰一些。

  首先,在js中,数据类型分为两种,基本类型(原始类型)和复杂类型,其中,基本类型是:String(字符串),Number(数值),Boolean(布尔值),还有undefinednull。复杂类型是Objecct(对象)。

  说到这里大家可能会有些疑问,只有这六种类型?那数组(Array),正则(RegExp),日期(Date)算是什么?其实他们都是Object(对象)的一个分支,换句话说它们都属于Object类型,这也正是js与众不同的地方——万物皆对象。而后面要聊的包括队列,栈,链表,集合,树,图等数据结构在js中的展现方式,也都是通过对象和原型来实现的。本文无意去详细的描述数据类型和数据结构的种类以及在js中的体现形式。所以点到为止。

  故事已经开始,请大家系好安全带,跟着我驰骋在在这篇广阔的土地上——数组

  先解释一下什么是数组吧,所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个“名”称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。这些无序排列的同类数据元素的集合称为数组。简单来说数组就是用于储存多个相同类型数据的集合。(当然,js中的数组也可以存储不同类型数据,但是!不建议这样做!)

  一、数组的创建和初始化

  相信很多小伙伴都知道创建一个数组十分容易:

var arr = [];

  这样我们就创建了一个数组,我们还可以用new关键字来创建并初始化一个数组:

//创建一个空数组
var newArr = new Array();
//创建一个指定长度的数组
var newLenArr = new Array(4);
//创建一个具有指定参数的数组
var numArr = new Array(1,2,3,4);

  当然,通过new关键字创建并初始化数组的方式并不推荐,这里只是给大家介绍一下。其实我们通过上面第一种方式来创建数组的本质就是通过new来实例化一个Array对象。OK,这里不多说它的实现原理,还是回到数组本身来吧。

  那么我们如何读取数组中的数据呢?很简单,我就一句话带过了,也就是通过中括号([ ])arr[2],来传递数值的位置,获取到对应位置的值,也可以通过这种方式来重新赋值。

  二、数组的增删

  接下来说说如何使用js数组自带的方法来实现数组头尾的增删:push(数组尾部插入元素),unshift(数组头部插入元素),pop(数组尾部删除元素)和shift(数组头部删除元素)

  1、push方法

  如果我不想使用push方法,有没有什么方式可以在数组的尾部插入一个元素呢?其实很简单,我们只需要把值赋给数组中最后一个空位上的元素就可以了。

var nums = [0,1,2,3,4];
nums[nums.length] = 5;

  我们通过length属性,获取该数组的长度是5,但是我们数组对应的下标是从0开始的,通过这样的方式,也就给数组的尾部插入了一个新的元素。当然,其实我们可以更方便的使用push来给数组的尾部插入一个元素:

var nums = [0,1,2,3,4];
nums.push(5);

  也可以得到同样的结果。当然,push也可以传入多个参数,依次的从尾部插入数组:

var nums = [0,1,2,3,4];
nums.push(5,6,6);
//[0,1,2,3,4,5,6,6]

  2、unshift方法

  那么同样的,如何在不使用原生方法的前提下给数组的头部添加一个元素呢?

var nums = [0,1,2,3,4,5,6];
for(var i = nums.length;i >= 0;i--){
nums[i] = nums[i - 1];
}
//[undefined, 0, 1, 2, 3, 4, 5, 6]
nums[0] = -1;
//[-1, 0, 1, 2, 3, 4, 5, 6]

  实际上,我们通过循环遍历,把nums数组中的每一位所对应的下标增加一个,也就是向后移动一位,那么这就导致了头部的位置空出(它的位置是存在的),但是此时我们并没有给空出的位置所对应的下标赋值,所以它的长度增加了值确实undefined,赋值之后,才会得到我们想要的结果。

  下面我们还是用unshift方法来给数组的头部插入新值:

var nums = [0,1,2,3,4,5];
nums.unshift(-1);
//[-1, 0, 1, 2, 3, 4, 5]
nums.unshift(-2,-3);
//[-2, -3, -1, 0, 1, 2, 3, 4, 5]

  那么要注意一点,在使用unshift传入多个参数的时候,他会把第一个参数放在数组的头部(以此类推),也就是说unshift方法会把所有的参数依照顺序插入数组,并不是我们想当然的那样从第一个参数依次添加进数组。

  3、pop方法

  如果我想要删除数组尾部的元素,我们可以使用pop方法,其实我们还是可以用js来模拟一下pop:

var nums = [0,1,2,3,4,5];
nums.length = nums.length - 1;
//[0, 1, 2, 3, 4]

  我们可以通过手动让数组的长度减少一位,就可以实现删除数组尾部的元素,当然也可以减少两位三位等。

  实际上,在日常开发中通常都会使用pop方法来删除数组尾部的元素(pop()方法没有参数,只是删除数组尾部的元素。):

var nums = [0,1,2,3,4,5];
nums.pop()
// [0, 1, 2, 3, 4]

  4、shift方法

  那么接下来我们看看如何从数组的首位删除元素:

var nums = [0,1,2,3,4,5];
for(var i = 0; i < nums.length; i++) {
nums[i] = nums[i + 1]
}
// [1, 2, 3, 4, 5, undefined]

  可以看到,我们最后一位是undefined,也就是说在最后一次的循环里,i + 1引用了一个数组里还未初始化的位置(开辟了空间但是未赋值),所以,这样的方式只是依次覆盖了上一位的值,并没有真正的删除元素。如果想要删除首位的元素,这就需要用到shift方法了。

var nums = [0,1,2,3,4,5];
nums.shift();
// [1, 2, 3, 4, 5]

  5、splice方法

  最后,我们看看如何使用splice()方法,在数组的任意位置添加和删除元素:

var nums = [0,1,2,3,4,5,6,7];
nums.splice(2);
//[0, 1]
//如果只加一个参数,说明删除从下标2开始的所有的后面的元素
var nums = [0,1,2,3,4,5,6,7];
nums.splice(2,1);
//[0, 1, 3, 4, 5, 6, 7]
//如果加入两个参数,则为删除从下标2开始的后面的几个元素。
var nums = [0,1,2,3,4,5,6,7];
nums.splice(2,1,"a","b","c");
//[0, 1, "a", "b", "c", 3, 4, 5, 6, 7]
//三个或多个参数,意味着删除从下标2(第一个参数)开始的后面的1个(第二个参数)元素,并在下标2的后面加入从第三个参数开始的后面的所有参数,把第二个参数设置为0就可以不删除元素从而实现从任意位置添加元素

  再多说一点,我们还可以使用delete操作符来删除数组中的元素,但是实际上,delete只是删除了对应下标上所存储的值,并没有同时把存储值得空间也删除掉,会导致对应位置上的值为undefined:

var nums = [0,1,2,3,4,5,6,7];
delete nums[2];
//[0, 1, undefined, 3, 4, 5, 6, 7]

  splice()方法是修改了原数组的。

  6、slice()

    slice()方法,会返回参数选定的范围的数组。该方法有两个参数,start(必选)和end(可选)。这两个值可以为负数,如果为负数则默认从尾部的第一个参数算起,也就是说-1就是数组的最后一个元素,-2就是数组的倒数第二个元素,以此类推。如果不传end,则默认从start开始直到数组最后一个元素都会被截取。

var nums = [0,1,2,3,4,5,6,6,7,"a",9,10,{name:"zaking"},["b","c"]];
var a = nums.slice(1,5);
console.log(a);//[1, 2, 3, 4]
var b = nums.slice(-1,5);
console.log(b);//[]
var c = nums.slice(-1,-5);
console.log(c);//[]
var d = nums.slice(-5,-1);
console.log(d);// ["a", 9, 10, {…}]
var f = nums.slice(5,1);
console.log(f);//[]
var x = nums.slice(5);
console.log(x);// [5, 6, 6, 7, "a", 9, 10, {…}, Array(2)]
var y = nums.slice(-5);
console.log(y)//["a", 9, 10, {…}, Array(2)]

  希望大家仔细看一下这个例子,当然,我还是一句话说明一下吧。

  其实主旨就是,你所传的参数无论正负,参数所限定的范围必须是包含数组元素的。

  那么数组的一些基本用法就先介绍到这里,后面应该还有两篇左右的长度来介绍数组。花费如此的篇幅,实在是数组真的极为重要,还请大家不要着急。当真正的学会了数组之后,再去看栈,队列这种数据结构,其实就很简单了。

  最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!

用js来实现那些数据结构01(数组篇01-数组的增删)的更多相关文章

  1. 用js来实现那些数据结构(数组篇01)

    在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念.那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记 ...

  2. 用js来实现那些数据结构15(图01)

    其实在上一篇介绍树结构的时候,已经有了一些算法的相关内容介入.而在图这种数据结构下,会有更多有关图的算法,比如广度优先搜索,深度优先搜索最短路径算法等等.这是我们要介绍的最后一个数据结构.同时也是本系 ...

  3. Java菜鸟学习笔记--数组篇(二):数组实例&args实例

    基本类型实例 //1.定义一个一维数组,先声明,在分配空间 int []number;//生命,没有初始化,number=null number=new int[5];//初始化为默认值,int默认值 ...

  4. 用js来实现那些数据结构—目录

    首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...

  5. 用js来实现那些数据结构及算法—目录

    首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...

  6. 用js来实现那些数据结构(数组篇03)

    终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式.那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀疑数组在JS中的重要性与实用性.这篇文章分为 ...

  7. 用js来实现那些数据结构03(数组篇03-排序及多维数组)

    终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式.那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀疑数组在JS中的重要性与实用性.这篇文章分为 ...

  8. (js描述的)数据结构 [数组的一些补充](1)

    (js描述的)数据结构 [数组的一些补充](1) 1. js的数组: 1.优点:高度封装,对于数组的操作就是调用API 2.普通语言的数组: 1.优点:根据index来查询,修改数据效率很高 2.缺点 ...

  9. 用js来实现那些数据结构07(链表01-链表的实现)

    前面讲解了数组,栈和队列.其实大家回想一下.它们有很多相似的地方.甚至栈和队列这两种数据结构在js中的实现方式也都是基于数组.无论增删的方式.遵循的原则如何,它们都是有序集合的列表.在js中,我们新建 ...

随机推荐

  1. 【vue报错】——listen EADDRINUSE :::8080 解决方案

    题原因: 此项错误表示 8080 端口被占用 解决方案一: 打开cmd输入:netstat -ano|findstr "8080"查看所有端口信息,并通过findstr “8080 ...

  2. 实用技能之Python打包制作成EXE可执行程序

    制作环境:Andconda3,python3.6 一.安装pyInstaller 方式一): 在命令行输入:pip install pyinstaller 方式二): ①   下载pyInstalle ...

  3. springMVC文件上传与下载(六)

    1..文件上传 在springmvc.xml中配置文件上传解析器 <!-- 上传图片配置实现类,id必须为这个 --> <bean id="multipartResolve ...

  4. linux下mysql 5.7.22 安装

    二进制安装 1.下载https://dev.mysql.com/downloads/mysql/5.6.html#downloads 2.官方文档https://dev.mysql.com/doc/r ...

  5. Potential Pythonic Pitfalls

    Potential Pythonic Pitfalls Monday, 11 May 2015 Table of Contents Not Knowing the Python Version Obs ...

  6. 使用nginx实现浏览器跨域请求

    跨域访问问题, 相信很多人都遇到过, 并且都用不同的办法去解决过. 方法有很多种, 不一一叙述了. 这里主要使用nginx反向代理来解决跨域问题. 啥是跨域? 假如你是百度开发人员, 在百度页面去请求 ...

  7. python操作haproxy.cfg文件

    需求 1.查 输入:www.oldboy.org 获取当前backend下的所有记录 2.新建 输入: arg = { 'bakend': 'www.oldboy.org', 'record':{ ' ...

  8. 关于ftp上传changeWorkingDirectory()方法的路径切换问题

    在上传时 FTPClient提供了upload方法,对于upload(file,path)的第二个参数path ,上传到哪里的这个路径, ftp是利用changeWorkingDirectory()方 ...

  9. Android几种强大的下拉刷新库

    BeautifulRefreshLayout 众多优秀的下拉刷新(除了我写的之外T_T) 说起下拉刷新,好像经历一段历史的洗礼... (1)在我刚学android的时候,用的是XListView,在g ...

  10. 将日期或数据转换为char数据类型 TO_CHAR(x[[,c2],C3])

    TO_CHAR(x[[,c2],C3])[功能]将日期或数据转换为char数据类型[参数]x是一个date或number数据类型.c2为格式参数c3为NLS设置参数如果x为日期nlsparm=NLS_ ...