一、Symbol数据类型
在ES6中,提出了一个新的基本数据类型Symbol
-
特点:
Symbol
的值是唯一的:解决命名冲突问题Symbol
的值,无法与其他数据进行计算,包括字符串拼接for in
,for of
遍历不会遍历Symbol
属性
-
使用:
-
传参标识
let symbol = Symbol('one') console.log(symbol) // Symbol(one) console.log(typeof symbol) // Symbol
-
调用
Symbol
函数得到值let symbol = Symbol() let obj = {} obj[symbol] = 'hello' console.log(obj) // {Symbol(): 'hello'}
-
内置
Symbol
值对象的
Symbol.iterator
属性,指向该对象的默认遍历器方法
-
二、Iterator迭代器
1、概念
iterator
是一种 接口机制,为各种不同的数据结构提供统一的访问机制
2、作用
- 为各种数据结构,提供一个统一的、简便的访问接口
- 使得数据结构的成员能够按照某种次序排列
- ES6创造了一种新的遍历命令
for of
循环,Iterator
接口主要供for of
消费
3、工作原理
- 创建一个指针对象(遍历器对象),指向数据结构的起始位置
- 第一次调用
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针会一直往后移动。直到指向最后一个成员 - 每调用一次
next
方法,都会返回一个包含value:当前成员的值
和done:布尔值,是否遍历结束
的对象,
4、具有Iterator
接口的数据
- Array
- arguments
- set容器
- map容器
- String
let arr =[1, 2, 3, 4]
for(let item of arr) {
console.log(item) // 1 2 3 4
}
5、自己实现一个Iterator
方法
方法实现:
function iteratorUtil(target) { // target表示传入的数据
let index = 0 // 表示 指针的起始位置
return { // 返回一个 next函数,里面有value、done值
next: function() {
return {value: target[index], done: index++ >= target.length}
}
}
}
let arr = [1, 2, 3, 4]
let iteratorObj = iteratorUtil(arr)
console.log(iteratorObj.next()) // {value: 1, done: false}
console.log(iteratorObj.next()) // {value: 2, done: false}
console.log(iteratorObj.next()) // {value: 3, done: false}
console.log(iteratorObj.next()) // {value: 4, done: false}
console.log(iteratorObj.next()) // {value: undefined, done: true}
6、用自己的方法,替换JS定义的
function iteratorUtil() {
let index = 0 // 表示 指针的起始位置
let that = this // 这个this,就是调用者,就是 循环的目标
return {
next: function() { // 使用保存的this,或者使用箭头函数的方法
return {value: that[index], done: index++ >= that.length}
// done: index++ >= target.length --> 表示,比较当前指针和数组长度,小于长度,就为false,大于等于就true,然后把 index++, 指针后移
}
}
}
let arr = [1, 2, 3, 4]
// 替换
Array.prototype[Symbol.iterator] = iteratorUtil
for (const item of arr) {
console.log(item) // 1 2 3 4
}
7、实现Array和Object都可以迭代的函数
function iteratorUtil() {
let index = 0 // 表示 指针的起始位置
let that = this // 这个this,就是调用者,就是 循环的目标
// 判断是否是Array,不是,走这里
if (!(this instanceof Array)) {
let keyArr = Object.keys(this)
return {
next: function () { // 使用保存的this,或者使用箭头函数的方法
return {
value: that[keyArr[index]],
done: index++ >= keyArr.length
}
// done: index++ >= target.length --> 表示,比较当前指针和数组长度,小于长度,就为false,大于等于就true,然后把 index++, 指针后移
}
}
}
else { // Array走这里
return {
next: function () { // 使用保存的this,或者使用箭头函数的方法
return {
value: that[index],
done: index++ >= that.length
}
// done: index++ >= target.length --> 表示,比较当前指针和数组长度,小于长度,就为false,大于等于就true,然后把 index++, 指针后移
}
}
}
}
let obj = {
name: 'Tom',
age: 18
}
Object.prototype[Symbol.iterator] = iteratorUtil
// 测试对象
for (const item of obj) {
console.log(item)
}
console.log(...obj)
let arr = [1, 2, 3, 4]
Array.prototype[Symbol.iterator] = iteratorUtil
// 测试数组
for (const item of arr) {
console.log(item)
}
console.log(...arr)
结果:
Tom
18
1
2
3
4