Symbol基本使用
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是Javascript语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol特点:
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用
for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
创建Symbol
let s = Symbol();
let s2 = Symbol('嘿嘿嘿')
let s3 = Symbol('嘿嘿嘿')
console.log(s2===s3) //false
//Symbol.for创建
let s4 = Symbol.for('嘿嘿嘿')
let s5 = Symbol.for('嘿嘿嘿')
console.log(s4===s5) //true
不能与其他数据进行运算
let result = s + 100 //报错
let result = s > 100 //报错
let result = s + '100' //报错
对象添加Symbol类型的属性
let game{…
//声明一个对象
let methods = {
up:Symbol(),
down:Symbol()
};
game[methods.up] = function(){
console.log('我可以改变形状')
}
geme[methods.down] = function(){
console.log('我可以下降')
}
Symbol的内置属性
hasInstance属性
class Person{
static [Symbol.hasInstance](param){
console.log(param)
console.log('我被用来检测类型了')
return false
}
}
let o = {}
console.log(o instanceof Person)
isConcatSpreadable属性
const arr=[1,2,3]
const arr2 = [4,5,6]
arr2[Symbol.inConcatSpreadable] = false; //表示是否可以展开
console.log(arr.concat(arr2))
迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Interator接口,就可以完成遍历操作
- 1.ES6创造了一种新的遍历命令for…of循环,Interator接口主要供for…of消费
- 2.原生iterator接口的数据
- Array
- Arguements
- Set
- Map
- String
- TypedArray
- NodeList
- 工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧']
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
迭代器的应用
//声明一个对象
const banji = {
name:'终极一班',
stus:[
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.interator](){
//索引变量
let index = 0
//
let _this = this
return {
next: function(){
if(index < this.stus.length){
const result = {value:this.stus[index],done:false}
//下标自增
index++;
//返回结果
return result;
}else{
return {value:undefined , done:true}
}
}
}
}
}
生成器
生成器函数式ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
声明方式
function * gen(){
console.log('hello')
}
let iterator = gen();
//console.log(iterator)
iterator.next();
function * gen(){
console.log(111)
yield '嘿嘿嘿' //yield起到函数代码的分隔符的作用 第一部分
console.log(222)
yield '哈哈哈' //第二部分
console.log(333)
yield '哦哦哦'
console.log(444)
}
let iterator = gen();
iterator.next(); //输出第一部分111
iterator.next(); //输出第二部分222
iterator.next(); //输出第三部分333
iterator.next(); //输出第四部分444
遍历
function * gen(){
console.log(111)
yield '嘿嘿嘿' //yield起到函数代码的分隔符的作用 第一部分
console.log(222)
yield '哈哈哈' //第二部分
console.log(333)
yield '哦哦哦'
console.log(444)
}
for(let v of gen()){
console.log(v);
}
生成器函数参数
function * gen(arg){
console.log(arg)
let one = yield 111;
console.log(one)
let two = yield 222;
console.log(two)
let three = yield 333;
console.log(three)
}
//执行获取迭代器对象
let iterator = gen('AAA')
console.log(iterator.next())
//next方法可以传入实参
console.log(iterator.next('BBB'))
console.log(iterator.next('CCC'))
console.log(iterator.next('DDD'))
- 下面为输出结果
生成器函数实例
实例一:回调地狱解决问题
//1s后控制台输出111 2s后输出222 3s后输出333
//回调地狱
// setTimeout(() => {
// console.log(111);
// setTimeout(() => {
// console.log(222)
// setTimeout(() => {
// console.log(333)
// }, 3000);
// }, 2000);
// }, 1000);
function one(){
setTimeout(() => {
console.log(111);
iterator.next()
}, 1000);
}
function two(){
setTimeout(() => {
console.log(222)
iterator.next()
}, 2000);
}
function three(){
setTimeout(() => {
console.log(333)
iterator.next()
}, 3000);
}
function *gen(){
yield one()
yield two()
yield three()
}
//调用生成器函数
let iterator = gen()
iterator.next()
实例二
//模拟获取 用户数据 订单数据 商品数据
function getUsers(){
setTiomeout(()=>{
let data = '用户数据'
//调用next方法,并且将数据传入
iterator.next(data)
},1000)
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据'
iterator.next(data)
},1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据'
iterator.next(data)
},1000)
}
function * gen(){
let users = yield getUsers();
console.log(users)
let orders = yield getOrders();
console.log(orders)
let goods = yield getGoods();
console.
}
//调用生成器函数
let iterator = gen();
iterator.next();

