最近看到es6中set与map,然后去了解了一下为什么es6中要新增这么两种数据结构,了解过之后我看的很懵逼,就想着从0开始整理一下几种常见的数据类型及其特点.
首先我们来了解下什么是数据结构?
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
数据结构大体有两种分类方式:逻辑结构和存储结构.
按照逻辑结构可分为线性结构和非线性结构,按照存储结构分为顺序存储结构,链式存储结构,索引存储结构和散列存储结构.
线性结构的数据类型:线性表,栈,队列和串
1.线性表:一个线性表表示具有n个数据元素的有限序列
2.栈:栈是一种具有线性结构的数据结构,是操作受限的线性表,栈的特点是后进先出,只能在栈顶进行插入和删除操作,入栈、出栈
3.队列:一种具有线性结构的数据结构,是操作受限的线性表,先进先出,只能在队尾插入元素和队头删除元素,称为入队列和出队列;
4.串(字符串):是零个或多个字符组成的有限序列,一般记为S=‘a1a2…..an’,属于取值受限的线性表
5.数组:n(n>1)个相同类型数据元素a0,a1,…,an-1构成的有限序列,且该有限序列存储在一块地址连续的内存单元中。
非线性结构的数据类型:广义表,树,图.文件
1.广义表 :是线性表的推广,是由零个或多个单元素或子元素所组成的有限序列
2.树:n(n>0)个结点的有限制,n==0为空树;非空树满足(有且只有一个特定的称为root的结点,其余n-1个结点可以划分成m个互不相交的有限集,没一部分又是一棵树) .二叉树是指满足每个结点的度都不大于2,每个结点的孩子结点次序不能任意颠倒的树。由多棵树组成森林
当然后在不同语言环境下,所体现的数据结构会有差异性,来了解一下javaScript中的数据结构:
堆(heap)和栈(stack)的概念
堆指的是堆内存,栈指的是栈内存,栈内存存储基本类型数据,堆用来存储引用类型的数据.堆,队列优先,先进先出(FIFO—first in first out);栈,先进后出(FILO—First-In/Last-Out)。
栈:由操作系统自动分配释放 ,内存大小相对固定,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
js中基本类型有五种,Undefined、Null、不是new出来的布尔、数字和字符串,它们都是直接按值存储在栈中的,每种类型的数据占用的内存空间的大小是确定的,并由系统自动分配和自动释放。这样带来的好处就是,内存可以及时得到回收,相对于堆来说,更加容易管理内存空间。
js中其他类型的数据被称为引用类型的数据(如对象、数组、函数等),它们是通过拷贝和new出来的,这样的数据存储于堆中。其实,说存储于堆中,也不太准确,因为,引用类型的数据的地址指针是存储于栈中的,当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据。
传值与传址
var aArray = [1,2,'s']; var bArray = []; var str = aArray[2] bArray = aArray; bArray[2] = 3 console.log(aArray)//[1,2,3] console.log(str)//s str = 'str' console.log(aArray)//[1,2,3]
因为aArray是数组,属于引用类型,所以它赋予给bArray的时候传的是栈中的地址(相当于新建了一个不同名“指针”),而不是堆内存中的对象的值。这种方式叫做传址,两个数组的指针指向同一内存地址,str的到的是一个基本类型的赋值,因此,str仅仅是从aArray堆内存中获取了一个数值,并直接保存在栈中。aArray、bArray都指向同一块堆内存,bArray修改的堆内存的时候,也就会影响到aArray,str是直接在栈中修改,并且不能影响到aArray堆内存中的数据。这种方式叫做传值.
深复制和浅复制最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用,深复制在计算机中开辟了一块内存地址用于存放复制的对象,而浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。