新增数据类型
大整数 bigint
已有介绍。它可以表示大于 2**53 - 1
的整数
符号 Symbol
它是 ES6 新引入的一种原始数据类型。使用Symbol()
可以直接生成一个新的值。
ES5 里面的对象的属性名是字符串,当我们使用别人的对象的时候,我不知道别人的对象有哪些属性,但是我又想添加一些新属性。如果直接写就有可能存在重名的情况,于是我们借助Symbol
来生成一个独一无二的值,这样就可以防止属性名的冲突了。
let symbol = Symbol()
console.log(Symbol()) //Symbol()
typeof symbol //"symbol"
它不是一个构造函数,不能用new
操作符。所以Symbol
的值也不是一个对象,不能添加属性,可以理解为一个字符串的数据类型
Symbol
的参数
字符串做参数:用于描述生成的Symbol
方便自己区分生成的Symbol
let name = Symbol("name"),
age1 = Symbol("age")
console.log(name, age1) //Symbol("name") Symbol("age")
name === age1 //false
let age2 = Symbol("age")
age1 === age2 //false
- 打印的时候可以区分你用的是哪个值
- 打印只是打印当前的
Symbol
的值的标识符,然而相同的标识符的Symbol
是不一样的
对象做参数:虽然可以使用,但是Symbol
本质内部对参数对象做了toString
方法,还是字符串。
Symbol
的计算问题
不能计算。除了toString
和转布尔类型,因为本质上Symbol
也是一个对象
let symbol = Symbol("1")
symbol.toString() //"Symbol(1)"
Boolean(symbol) //true
Number(symbol) //报错
Symbol
作属性名
它的存在就是做一个属性名的
let obj = {},
s1 = Symbol()
obj[s1] = "value of Symbol"
//或者
obj {
[s1]: "value of Symbol"
}
//Object.defineProperty
Object.defineProperty(obj, s1, {
value: "value of Symbol"
})
obj.s1 //等价于obj["s1"] undefined
obj[s1] //value of Symbol
obj[s1] = 123
var toString = Symbol("toString")
Object.prototype[toString] = function() {
return 1
}
var a = {
a: 1,
}
a.toString() //"[Object object]"
a[toString]() // 1
在对象内部定义Symbol
属性的时候必须加方括号,不然解析会被认为是字符串。
Symbol
作为属性名的遍历
for...in
和for...of
都无法遍历到Symbol
值的属性, Symbol
值作为对象的属性也无法被Object.keys()
和Object.getOwnPropertyNames()
来获取。
可以使用Object.getOwnPropertySymbols()
来获取。
let s1 = Symbol("s1"),
s2 = Symbol("s2")
let o = {}
o[s1] = "symbol s1"
o[s2] = "symbol s2"
o["s3"] = "s3"
for (let i in o) {
console.log(i) //"s3"
}
Object.keys(o) //["s3"]
Object.getOwnPropertySymbols(o) //[Symbol(s1), Symbol(s2)]
Symbol.for()
和Symbol.keyFor()
Symbol.for
接受一个字符串参数,查询有没有这个参数的Symbol
值,
有的话就直接返回这个Symbol
值,没有就返回一个这个参数的Symbol()
。
let s1 = Symbol("s1")
let s2 = Symbol.for("s2") //Symbol("s2")
s2 === Symbol.for("s2") //true
Symbol.keyFor
函数是用来查询Symbol
的登记状态的,如果没有就返回undefined
,而Symbol.for
会将生成的 Symbol 值登记到全局环境中,Symbol.keyFor
会查询到Symbol.for
函数生成的Symbol
值
let s1 = Symbol.for("s1"),
s2 = Symbol.for("s2"),
s3 = Symbol("s3"),
s4 = Symbol("s4")
console.log(Symbol.keyFor(s1)) //"s1"
console.log(Symbol.keyFor(s2)) //"s2"
console.log(Symbol.keyFor(s3)) //undefined
内置的Symbol
的值
Symbol 提供了 11 个内置的属性,分别是
Symbol.hasInstance
- 使用
instanceOf
方法时调用此属性,判断某一对象是否是某构造函数的实例
javascriptclass OneEnd { // 判断末尾是否为0 static[Symbol.hasInstance](num) { return Number(num) % 10 == 1 } } "123" instanceof ZeroEnd //false "1230" instanceof ZeroEnd //true
- 使用
Symbol.isConcatSpreadable
- 作为数组连接的时候是否允许展开,默认可以
javascriptlet arr1 = [1, 2], arr2 = [3, 4] arr2[Symbol.isConcatSreadable] //undefined arr1.concat(arr2, 5) //[1, 2, 3, 4, 5] arr2[Symbol.isConcatSpreadable] = false arr1.concat(arr2, 5) //[1, 2, [3, 4], 5] arr2[Symbol.isConcatSpreadable] = true arr1.concat(arr2, 5) //[1, 2, 3, 4, 5]
Symbol.species
Symbol.match
Symbol.replace
Symbol.search
Symbol.split
Symbol.iterator
指向默认遍历方法。见生成器函数章节
Symbol.toPrimitive
Symbol.toStringTag
内置的
Object.prototype.toString()
方法会去读取这个返回javascript//基本类型即便没有 toStringTag 属性,也能被 toString() 方法识别并返回 Object.prototype.toString.call([1, 2]) //"[object Array]" //非基本类型需要有toStringTag ; ({}).toString.call(function*() {}) //"[object GeneratorFunction]" //自己的类需要自己定义[Symbol.toStringTag]接口 class ValidatorClass { get[Symbol.toStringTag]() { return "Validator" } }
Symbol.unscopables
集合 Set
Set 是一个构造函数,用来生成 Set 的数据结构,类似数组,但是成员值都是唯一的,没有重复
const s1 = new Set()[(1, 1, 1, 3, 2, 565, 76)].forEach((i) => s1.add(i))
for (let i of s1) {
console.log(i)
}
//1, 3, 2, 565, 76
//解构
console.log([...s1]) //[1, 3, 2, 565, 76]
//接受数组参数新生成set
const s2 = new Set([1, 2, 3, 5])
数据去重简单做法
;
[...new Set(arr)] //
实例方法
add
添加元素,返回Set
本身size
返回实例成员长度delete
删除某个具体的值,返回true
或者false
表示成败clear
清空,无返回has
查询参数是否是set
的成员
Array.from()
方法可以传入set
实例对象转数组。
枚举方法
Set 数据类型有四个枚举方法,用于遍历成员。
keys
: 返回枚举的键名,等价于键值values
: 返回枚举的键值entries
: 返回键值对的遍历器。forEach
: 使用回调函数遍历每一个成员
javascriptlet set = new Set([1, 2, 3, 4]) for (let i of set.keys()) console.log(i) //1 2 3 4 for (let i of set.values()) console.log(i) //1 2 3 4 for (let i of set.entries()) console.log(i) //[1, 1] [2, 2] [3, 3] [4, 4] set.forEach((i) => console.log(i)) //1 2 3 4
映射 Map
原生 JavaScript 的对象的本质就是一个由键与值的映射,值可以是任意数据类型,但是键只能是字符串。
es6 为了拓展键名的范围,使用了 Map,让键名成为复杂对象
let el = document.querySelector(".box"),
map = new Map(),
content = {
description: "这是主要演示区域",
belongTo: "page1",
coder: "Gin",
}
map.set(el, content) //返回Map对象
map.has(el) //true
map.has(content) //false
map.get(el) === content //true
示例方法
size
返回长度set
设置映射关系,键名第一个参数,键值是第二个参数,返回本身has
查询键名,返回布尔值get
传入键名,返回键值,没有就是返回 undefineddelete
传入键名,返回布尔类型,失败是 falseclear
清空map
枚举方法
keys
: 返回枚举的键名values
: 返回枚举的键值entries
: 返回键值对的枚举器。forEach
: 使用回调函数遍历每一个成员