数据类型
Map()
Map()
类型实际上是键值对的有序集合,键和值是任意类型,可以使用构造函数来创建,一个键对应一个值
const m = new Map()
const m2 = new Map([
['name', '张三'],
['age', '12']
])
console.log(m2)
// Map(2) {'name' => '张三', 'age' => '12'}
size
方法可以获取键值的数量,相当于数组的 length
方法
const m2 = new Map([
['name', '张三'],
['age', '12']
])
console.log(m2.size) // 2
set()
方法添加元素,接收两个参数:键/值
const mapList = new Map()
mapList.set('name', '张三')
mapList.set('age', 12)
console.log(mapList)
// Map(2) {"name" => "张三", "age" => 12}
get()
方法通过指定键名获取键值
const mapList = new Map()
mapList.set('name', '张三')
mapList.set('age', 12)
console.log(mapList.get('name'))
// 张三
has()
方法检测集合中有无指定元素,返回布尔值
const m2 = new Map([
['name', '张三'],
['age', '12']
])
console.log(m2.has('name')) // true
console.log(m2.has('name2')) // false
delete()
方法可删除元素
const m2 = new Map([
['name', '张三'],
['age', '12']
])
m2.delete('name')
console.log(m2) // Map(1) {'age' => '12'}
clear()
方法可以清楚所有的键值
const m2 = new Map([
['name', '张三'],
['age', '12']
])
m2.clear()
console.log(m2) // Map(0) {size: 0}
keys()
方法可以获取到所有的键
const m = new Map([
['name', '张三'],
['age', '12']
])
console.log(m.keys()) // MapIterator {'name', 'age'}
values()
可以获取每一项的值
const m = new Map([
['name', '张三'],
['age', '12']
])
console.log(m.values()) // MapIterator {'张三', '12'}
Map
与 Objet
类型不同的是,它可以用任意的键作为键名
function fun() {}
const sy = Symbol()
const obj = {}
const m = new Map([
[fun, '这是函数'],
[sy, '这是 Symbol'],
[obj, '这是 obj']
])
console.log(m.get(fun)) // 这是函数
console.log(m.get(sy)) // 这是 Symbol
console.log(m.get(obj)) // 这是 obj
console.dir(m)
打印结果
Map(3)
[[Entries]]
0: {function fun () { } => "这是函数"}
1: "这是 Symbol"
2: {Object => "这是 obj"}
size: 3
[[Prototype]]: Map
可以使用 entries 方法进行迭代
const m = new Map([
['name', '张三'],
['age', '12']
])
for (const item of m.entries()) {
console.log(item)
// ['name', '张三']
// ['age', '12']
}
也可以使用 [Symbol.iterator]()
方法进行迭代
[Symbol.iterator]()
和 entries()
是全等的
console.log(m.entries === m[Symbol.iterator]) // true
const m = new Map([
['name', '张三'],
['age', '12']
])
for (const item of m[Symbol.iterator]()) {
console.log(item)
// ['name', '张三']
// ['age', '12']
}
或者使用数组方法进行遍历
const m = new Map([
['name', '张三'],
['age', '12']
])
m.forEach((item, value) => {
console.log(item, value)
// 张三 name
// 12 age
})
把数组复制到映射
const arr = ['css', 'html', 'js']
const m = new Map(
arr.map((item, index) => {
return [index + 1, item]
})
)
console.log(m)
打印结果
Map(3) {1 => 'css', 2 => 'html', 3 => 'js'}
WeakMap()
WeakMap()
是 Map()
的一个兄弟,但是也是有些区别的
WeakMap()
的键只能是 Object
类型
- 错误的
const wm = new WeakMap([['age', '12']])
console.dir(wm) // TypeError:用作弱映射键的值无效
- 正确的
const obj = {}
const wm = new WeakMap([[obj, '12']])
如果想使用字符串进行作为键,可以先包装成对象再作为键
const obj = {}
const str = new String('name')
const wm = new WeakMap([
[obj, '12'],
[str, '张三']
])
还有不同的是:
WeakMap()
不可被迭代clear()
方法不能使用
Set()
ES6 提供了新的数据结构 Set()
。它类似于数组,但是成员的值都是唯一的,没有重复的值,很多时候它都要强于 Map()
创建一个 Set
数据结构
const s = new Set()
Set()
和 Map()
类似,有着很多共同效果的方法:
size
方法获取元素的数量add()
方法添加元素delete()
方法删除元素has()
方法检测集合中有无指定元素,返回布尔值clear()
方法可清空所有元素
values()
和 keys()
方法可以获取其中的每一项进行遍历
values()
和 keys()
是全等的,所以用哪个都可以
const s = new Set([1, 2, 3, 4])
console.log(s.values === s.keys) // true
console.log(s.keys()) // SetIterator {1, 2, 3, 4}
for (const item of s.keys()) {
console.log(item)
}
// 1
// 2
// 3
// 4
将 Set 转换为数组
可以使用 Es6 的扩展运算符 ...
对 Set
展开进行转换
const setArr = new Set([1, 3, 3, 3, 3, 4, 6])
const arr = [...setArr]
console.log(arr)
// (4) [1, 3, 4, 6]
WeakSet()
WeakSet()
是 Set()
的一个兄弟,但是也是有些区别的
WeakSet()
的键只能是 Object
类型
WeakSet()
不可被迭代clear()
方法不能使用
Symbol()
Symbol 数据库类型是特点是:值是唯一的
可以通过Symbol()
创建一个 Symbol()
let a = Symbol()
let b = Symbol()
console.log(typeof a) // Symbol
console.log(a === b) // false
Symbol 并不是一个对象,可以把它理解为一个字符串,一个永远都不会重复的字符串,所以它是原始类型。
可以给 Symbol 添加一个描述:
const a = Symbol('这是一段文字')
const b = Symbol('你好吗')
用 js 内置的方法 description
提取出描述信息,并以字符串形式打印
const a = Symbol('这是一段文字')
const b = Symbol('你好吗')
console.log(a.description) // 这是一段文字
console.log(b.description) // 你好吗
除此之外,还可以使用
Symbol.for()
来定义
这样定义的也可以在内部添加描述,但是这样的好处是:如果两次定义完全一样,那么两个变量会公用一个内容地址:
const a = Symbol.for('这是一段文字')
const b = Symbol.for('这是一段文字')
console.log(a === b) // true
那么这样再判断的话,两个变量就相等了
这样声明的话,可以使用 Symbol.keyFor()
来获得描述的文字
const a = Symbol.for('这是一段文字')
console.log(Symbol.keyFor(a)) // 这是一段文字
实际应用,当有两个人的名字的一样的时候,可以使用 Symbol
来定义每个键值作为区分:
const user1 = {
name: '李四',
key: Symbol()
}
const user2 = {
name: '李四',
key: Symbol()
}
const obj = {
[user1.key]: {
js: 100,
css: 20
},
[user2.key]: {
js: 30,
css: 21
}
}
console.log(obj) // {Symbol(): {…}, Symbol(): {…}}
console.log(obj[user1.key]) // {js: 100, css: 20}
console.log(obj[user2.key]) // {js: 30, css: 21}
在对象中,如果存在 Symbol 类型时,通过普通的for in
或者 for of
循环是遍历不到的:
const age = Symbol('age')
const obj = {
name: '张三',
[age]: 12
}
// 普通的方式遍历只能得到普通的值
for (const key of Object.keys(obj)) {
console.log(key) // name
}
// 使用 Object.getOwnPropertySymbols() 方法之可以遍历出 Symbol 类型
for (const key of Object.getOwnPropertySymbols(obj)) {
console.log(key) // Symbol(age)
}
// 如果想要遍历出所有的类型,需要使用 Reflect.ownKeys() 静态方法才可以实现
for (const key of Reflect.ownKeys(obj)) {
console.log(key)
// name
// Symbol(age)
}
JSON
JSON.stringify()
使用 JSON.stringify()
方法可以将对象转换为 JSON 对象
const obj = {
name: '张同学',
age: 39,
arr: [1, 2, 3, 4]
}
console.log(JSON.stringify(obj))
// {"name":"张同学","age":39,"arr":[1,2,3,4]}
也可以接收第二个参数,用于过滤,可以接收一个数组或函数
const obj = {
name: '张同学',
age: 39,
arr: [1, 2, 3, 4]
}
console.log(JSON.stringify(obj, ['age']))
// {"age":39}
通过第二个参数过滤出 age
第三个参数是代表每行的缩进数量,最大为 10
const obj = {
name: '张同学',
age: 39,
arr: [1, 2, 3, 4]
}
console.log(JSON.stringify(obj, null, 2))
结果如下:
{
"name": "张同学",
"age": 39,
"arr": [1, 2, 3, 4]
}
JSON.parse()
使用 JSON.parse()
方法可以将 JSON 对象转换为对象
const json = `{"name":"张同学","age":39,"arr":[1,2,3,4]}`
console.log(JSON.parse(json))
// {name: '张同学', age: 39, arr: Array(4)}
FormData()
创建一个 formdata
const fd = new FormData()
fd.append('name', 'data')
append
方法接收两个参数 键和值
使用 FormDate 就不需要给 xhr 对象设置响应头了,因为 xhr 对象可以识别作为 FormDate 实例传入的数据类型并自动配置响应头