- 发布于
Symbol及Map
- Authors
- Name
- 田中原
Symbol
es6中新增的一种数据类型,表示独一无二的值
基本数据类型: String Number Boolean null undefined Symbol
引用数据数据类型: Object
创建:
let s1 = Symbol()
typeof s1 // 'symbol'
注意:
1.Symbol不能使用new调用,原因在于symbol是一个原始类型的值,不是对象
2.Symbol函数接受一个字符串作为参数,仅仅表示对Symbol的描述,主要是为了在控制台显示,或者转为字符串的时候,比较容易区分
eg:
let s1 = Symbol()
let s2 = Symbol()
console.log(s1,s2). //Symbol() Symbol()
let s3 = Symbol('js')
let s4 = Symbol('html')
console.log(s3,s4) //Symbol(js) Symbol(html)
console.log(Symbol('html') === Symbol('html')) //false 参数仅仅是Symbol的描述,不代表其他意义
3.如果Symbol参数是一个对象,就会调用该对象的toString方法,将其转为字符串然后生成一个Symbol值
eg:
const obj = {
toString() {
return 'abc'
},
}
console.log(Symbol(obj)) // Symbol(abc)
const obj = {
name: 'aa',
}
console.log(Symbol(obj)) //Symbol([object object])
Symbol类型的转换
1.转换成字符串
String(symbol('haha'))
2.转换成Boolean
console.log(!!Symbol()) //true
3.不能转换成数字,不能进行任何运算
console.log(Symbol('haha') + 'hello') //报错
4.作为对象的属性名(因为每一个Symbol值都是不相等的,这意味着Symbol可以作为标识符用于对象的)
let s = Symbol('s')
const data = {
[s]: 'haha',
}
console.log(data) //{Symbol(s): 'haha'}
注意:Symbol()作为属性名不能被for..in, for..of遍历,也不能被Object.keys(),Object.getOwnPropertyNames()返回,但是它也不是私有属性,可以通过Object.getOwnPropertySymbols方法获得一个对象的所有的Symbol属性名
eg:
let obj = {},
foo = Symbol('foo')
Object.defineProperty(obj, foo, {
value: 'footer',
})
for (let i in obj) {
console.log(i) //没有返回值
}
console.log(Object.getOwnPropertyNames(obj)) // []
console.log(Object.getOwnPropertySymbols(obj))[Symbol(foo)]
const data = {
[Symbol()]: 123,
}
console.log(data) //{Symbol():123}
console.log(data[Symbol()]) //undefined
console.log(Object.getOwnPropertySymbols(data)) //[Symbol()]
console.log(Object.getOwnPropertySymbols(data)[0]) // 123
数据结构Set
类似于数组,成员的值都是唯一的,没有重复的值。
1.如何创建一个Set
const set = new Set()
2.Set类的属性
var set = new Set([1, 2, 3, 4])
set.size // 4
3.Set类的方法
set.add(value)
:添加一个数据,返回Set结构本身
1)set.add('a').add('b').add('c'). //添加多个值
new Set([1,2,3]) // 或者直接当参数传进
注意:set不会对所存储值进行强制类型转换
Object.is(new Set().add(5), new Set().add('5')) //false
set.delete(value)
:删除指定数据,返回布尔值,表示是否删除成功
2) set.delete('a') // true
set.delete('a'). // false
set.has(value)
:判断该值是否是Set成员,返回一个布尔值
3) console.log(set.has('a')). //false
console.log(set.has('b')). //true
set.clear()
:清除所有数据,并没有返回值
4)set.keys()
:返回键名的遍历器
5)
const s = new Set([1,2,4])
console.log(s.keys())
set.values()
:返回值的遍历器
6) console.log(s.values())
set.entries()
:返回键值对的遍历器
7 ) console.log(set.entries())
set.forEach()
:使用回调函数遍历每个成员
8)var set = new Set([1,2,4])
set.forEach((value, key, ownerSet) => {
console.log(`${key}=${value}`)
console.log(ownerSet === set). //true
})
将set转换成数组:
const set = new Set([1,2,4])
[…set]
Array.from(set)
用途:
a.数组去重
const arr = [{}, 1, 2, 3, 1, 4, 'a', 3]
console.log([...new Set(arr)]) //[{},1,2,3,4,'a']
b.合并去重
let a = new Set([1, 2, 3])
let b = new Set([3, 2, 5])
let union = new Set([...a, ...b])
console.log([...union]) // [1,2,3,5]
数据结构Map
是一种存储着许多键值对的有序列表,键和值支持所有数据类型
以前:object只能用字符串当做键
eg:
let data1 = { a: 1 },
data2 = { b: 2 },
obj = {}
obj[data1] = 1
obj[data2] = 2
console.log(obj) // {[object Object]: 2}
而map可以解决以上问题
var map = new Map().set({}, 1).set({}, 2)
console.log(map) // {Object{}=>1, Object{}=>2}
1.创建Map
在创建的时候可以初始化参数,传的是二维数组,里面的数组是键值对的形式
const map = new Map([
["a", 1],
["b", 2]
])
console.log(map). // {"a" => 1, "b" => 2 }
2.Map属性
map.size:当前数据结构中键值对的个数
3.Map的方法
1)set(key, value):设置键名key对应的键值为value,返回整个Map结构,如果key已经有值,则键值会被更新,否则就新生成该键值对
eg:
const map = new Map()
map.set('a',1).set('b',2).set('b',3) /*链式写法*/
console.log(map). //{"a" => 1, "b" => 3}
2.get(key):get方法读取key对应的键值,如果找不到key,返回undefined
console.log(map.get('a')) //1
console.log(map.get('c')) //undefined
3.delete(key):删除某个键,删除成功返回true,否则返回false
console.log(map.delete('a')) // true
console.log(map.delete('d')) // false
4.has(key):方法返回一个布尔值,表示某个键是否在当前Map对象之中
console.log(map.has('a')) // false
console.log(map.has('b')) // true
5.clear(): 清除所有数据,没有返回值
map.clear()
map.size //0
6)keys():返回键名的遍历器
7)values():返回值的遍历器
8)entries():返回键值对的遍历器
9)forEach():使用回调函数遍历每个成员
5,6,7,8,9 与Set类似
使用for..of遍历
const m = new Map()
m.set('a', 1).set('b', 2).set('c', 3)
for (let [key, value] of map) {
consoel.log(key, value)
}
map转换成数组:
[…map]
Array.from(map)
map转换成对象:
function strMapTObj(strMap) {
let obj = Object.create(null)
for (let [k, v] of strMap) {
obj[k] = v
}
return obj
}
const map = new Map().set('yes', true).set('no', false)
strMapTObj(map) // {yes: true, no: false}
对象转换成map:
function objToStrMap(obj) {
let strMap = new Map()
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k])
}
return strMap
}
objToStrMap({ yes: true, no: false }) // Map('yes'=> true, 'no'=>false)
Map在使用过程中一些注意事项
const map = new Map()
map.set(NaN, 10).set(NaN, 100). //{NaN => 100}
也就是说在Map数据结构中认为NaN是同一个键-