zweizhao.github.io

项目,文章,随笔,博客,Markdown,个人网站,人生感悟。

View on GitHub

常用数据结构:Array, Object

不常用数据结构:Set, WeakSet, Map, WeakMap

结构型数据:JSON

特殊结构:Function


常用数据结构

结构 构造 字面量 说明
Array new Array() [a, b, c, d] 有序排列数据
Object new Object() {key: value} 对象,以键值对(key-value)的形式处理数据

日常使用强烈推荐使用字面量方式创建,以下能字面量就字面量说明,构造方法又是长篇大论,这里不做表述。

无论什么数据格式或结构,创建并赋值后,都会成为其对应的数据对象,获取其对象本身应具有的所有方法(或属性) 如:var a = 'aaa',此后的a便获取了字符串对象即String的所有方法(或属性),a.length就是3,等等。

Array

数组,列表。按照顺序排列数据,或者说内部数据是按照自然数顺序排列(0,1,2,3,4…n),如下:

// 字面量创建
var arr = [1, 2, 3, 4]

// 按照自然数索引获取,记住,是自然数,就是说从0开始索引,0为第一个,1为第二个……
arr[0] // 1
arr[1] // 2
arr[2] // 3
arr[3] // 4

下面简单介绍一些常用方法或属性:

方法(或属性) 说明
length 长度,属性
push 尾部添加一个元素
pop 删除尾部的元素
shift 删除第一个元素
unshift 添加元素到头部
splice 替换数据(根据不同业务,可实现删除,插入以及替换功能)
slice 截取数组
concat 拼接数组
join 数组转字符串
indexOf 查找元素索引

实例如下,其中array = [3, 1, 2] 每次使用都是这个值,不因为例子而更改

array.length 3,获取数组的长度

array.push(4) array = [3, 1, 2, 4],自身添加到最后一个,返回长度

array.pop() array = [3, 1],自身删除最后一个,返回 pop

array.shift() array = [1, 2] ,删除数组第一个元素, 并返回该元素

array.unshift(4) array = [4, 3, 1, 2],添加若干到开头, 返回长度

arr = array.slice(0, 1) arr = [3], array 不变,从下标 0,到下标 1(下标可以是负数),返回新数组单不包含最后一个

arr = array.slice() arr = [3, 1, 2],深拷贝的一种方法

arr = array.concat(4, 5) arr = [3, 1, 2, 4, 5],连接若干数组或数组后添加值

arr = array.concat() arr = [3, 1, 2],深拷贝的另一种方法

arr = array.join('-') arr = “3-1-2”,数组转字符串,不传参数默认使用逗号

arr = array.indexOf(1) arr = 1,获取1这个元素的索引位置,第二个,所以是1

所谓返回值是对方法(即函数)的一种特性表述,可以简单理解成,函数的功能是完成一件事情,返回值就是这件事情完成后的结果,比如有个函数(func1)的作用的生成100这个数(虽然毫无意义),那么就可以表述:var a = func1(),此时a就是100了。意义就是a接受了func1的返回值。

以下请自行查阅:

方法(或属性) 说明
lastIndexOf 反向查找元素索引
forEach 遍历数组元素
map 遍历数组元素
filter 过滤数组
every 检查数组是否全部符合某条件
some 检查数组是否存在元素符合某条件
reduce 迭代数组所有元素处理
reduceRight 反向迭代数组所有元素处理

Object

我们常说的对象,字典,键值对。数据储存下来是没有前后顺序的,或许你会在相同的运行环境下,每次打印都是一样的顺序,但是事实上它就是 无序 的,切记。

创建与获取如下:

var obj = {
    a: 1,
    b: 2
}

obj.a // 1
obj[b] // 2

以上两种获取方式请注意,第一种是绝对常用模式,几乎没什么人会愿意多打[]的,但是[]的存在价值是有的,比如obj.x其中x如果是合法字符串还好,如果x是abc-xyz这种类型,则使用.就会非法,而此时使用obj['abc-xyz']即可,注意里面是字符串。

Object没有什么特殊的常用方法(或属性),因为你要什么,自己补充什么,如下:

var obj = {
    num1: 1,
    func1: function() {
        return '我是函数'
    },
}

obj.num1 // 1
obj.func1() // “我是函数”

看看下面这个,有没有什么感觉?

var array= {
    length: 1,
    indexOf: function(item) {
        return 2
    }
}

array.length // 1
array.indexOf('x') // 2

是不是很像数组的操作?

不要误解数组是上面这个对象啊,我只是想说,你要啥,自己补充啥,自己创建一个数组结构都可以。

对象的键值对里面的值,就是key-value的value也可以是Object,所以Object可以非常非常复杂(数组也是)。

数组与对象是可以互相套用的,虽然理论上可以无限套用下去,但请在实际使用中避免过多混合套用。

delete

一个比较重要的操作符,或者说是常用处理Object的一个方式:

delete obj.x 删除对象obj的x键值对,返回值是个布尔值,说明有没有删除成功。

delete写法有两种,delete obj.xdelete(obj.x),这里要注意,形如delete或typeof这种,不是函数,他们是跟(++自增、–自减)一样的一元操作符,使用括号不是函数调用的意思。

严格来说delete可以操作所有引用,因此可以操作Object属性的引用。

delete示例:

var arr = [1, 2, 3]
var obj = {
    a: 1,
    b: 2
}

delete arr[1] // true
arr // [1, empty, 3],会删除索引为1元素的内容,但是不删除位置
delete obj.a // true
obj // {b: 2},a的键值对拿走了,干干净净

delete arr // true
arr // arr is not defined

delete obj
obj // obj is not defined

delete arr // true,此时的arr已经没有了,相当于delete个空,允许。
delete obj // 一样

由上方示例可以看出,delete在数组上使用时比较坑的,所以常见一点还是在Object上面使用。

别问{} + 1是多少,首先确实是当做0处理,但是实际中完全没有意义,因为数组里面假如是纯字符数组或纯数字数组,使用加减可以考虑省事,但是对象加减,当单纯是{}时候代表的不是Object,是代码块!当你使用new Object()填充数据时候,加减第一没有意义,第二任何情况结果都是(拿+1做示例)"[object Object]1"{a: 1, b: 2} + 1是会报错,语法不正确。


不常用数据结构

简单介绍下Set,Map

Set

集合,你可以简单理解成键值对一样从而省略值得Object,也可以理解成被{}包裹的数组(不能重复,且无索引),常用来数组去重,代码看懂即可:

var arr = [1,2,3,4,4,2,1,5]
var set = new Set(arr)
set // {1, 2, 3, 4, 5}
方法(或属性) 说明
size 元素的个数,属性
add 添加元素
delete 删除元素
has 检查是否有某个元素
keys 所有元素

拿上面那个set做实例:

set.size // 5
set.add(6) // {1, 2, 3, 4, 5, 6}
set.delete(2) // {1, 3, 4, 5, 6}
set.has(2) // false
set.has(1) // true
set.keys() // {1, 3, 4, 5, 6}

Set可以通过for of遍历取值

Map

Map简单理解成是可以自定义键的Object,Object的键无法使用一些奇葩类型做键,比如对象不能用对象字面量做键,需要这样{'{a:1}' : 1}才行,因为此时键是字符串,但是Map就可以使用对象字面量做键。

那么如果有这种特殊需求,就可以考虑使用Map了,我个人业务上从来没用到过,个人暂时不建议太多时间关注这块内容,故跳过。

WeakSet与WeakMap

这两个与Set和Map主要差异是,元素(或value)只能是引用类型,即数组,对象或函数类型,避免内存泄漏。

知道有这个东西就行,一样pass。


结构型数据

有很多种,比如表单,但是一定要尽量使用JSON,就是好用,谁用谁知道。谁让你不用JSON,你们确实需要好好谈谈了。

JSON

非常简单的理解方式,当做Object处理即可,数据结构与Object一模一样(转换时候Function值会丢失,下面会介绍如何处理),即key-value形式, 但是有个特殊,就是数组也当做合法的JSON结构。

// JSON
{
    key1: value1,
    key2: value2,
    ...
    keyn: valuen
}

// 数组也行
[value1, value2, value3]

以上value当然可以是任何类型,除了Function,因为最终都是转成了String类型进行传输的。

那么如果你遇到了需要传输Function的业务,如下处理:

var json = {
    a: 1,
    b: function() {
        return 'function'
    }
}

// 会出现的问题
// JSON.stringify(json) // "{"a":1}",函数那个丢失了,注意已经转成字符串了

// 处理方式
json.b += '' // 记得之前数据类型时候字符串加减法么,加空字符串相当于强制转为字符串

JSON.stringify(json) // "{"a":1,"b":"function() {\n        return 'function'\n    }"}",成功转换

JSON两个关键方法

方法 说明
stringify 对象(或数组)转字符串
parse 字符串转对象(或数组)
JSON.stringify([1]) // "[1]"
JSON.parse("[2]") // [2]

特殊结构

Function

严格来说,Function不是数据结构,但是它可以实现数据结构功能,或者存储数据。这里超纲,牵扯到了“类”,简单了解即可。

function MyObj() {
    this.head = 'head'
    this.foot = 'foot'
    this.obj = {a: 1}
    this.arr = [1,2]
    this.func = function() {
        return 'func'
    }
}

var obj = new myObj()

obj.func += ''

obj // "{"head":"head","foot":"foot","obj":{"a":1},"arr":[1,2],"func":"function() {\n        return 'func'\n    }"}"

typeof obj // "object"

如果文章对你有一点点帮助,我就非常开心了。

我是风蓝小栖,如果喜欢我的文章,请关注一下,满满的干货!