Symbol
Symbol特点
1 Symbol 的值是唯一的 用来解决命名冲突的问题
2 Symbol 值不能与其他数据进行运算
3 Symbol 定义的对象属性不能使用 for… In 循环遍历 但是可以使用 Reflect。ownKeys 来获取对象的所有键名
Symbol 基本使用
适用 唯一性的场景
// 创建symbol
let s = Symbol();
let s2 = Symbol('Tom');
let s3 = Symbol('Tom');
console.log(s2 == s3);
// Symbol.for 创建
let s4 = Symbol.for('Tom');
let s5 = Symbol.for('Tom');
console.log(s4 == s5);
// 不能与其他数据进行运算
symbol 内置值
class Person {
static[Symbol.hasInstance](param) {
console.log(param);
console.log('我被用来检测类型了');
return true
}
}
let o = {};
console.log(o instanceof Person);
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false // 后面添加的对象是否可以展开
console.log(arr.concat(arr2));
symbol 创建对象属性
// 向对象中添加方法 up down
let game = {
name: '俄罗斯方块',
up: function() {},
down: function() {}
};
// 声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.down] = function() {
console.log('我可以改变形状');
}
game[methods.up] = function() {
console.log('我可以上升');
}
game[methods.down]();
console.log(game);
let say = Symbol();
let youxi = {
name: '狼人杀',
[say]: function() {
console.log('我可以发言');
},
[Symbol('zibao')]: function() {
console.log('我可以自爆');
}
}
console.log(youxi);
youxi[say]();
迭代器 Iterator
任何数据结构只要部署 Iterator 接口 就可以完成遍历操作
// 声明一个数组
const names = ['Tom', 'Jhon', 'Jack'];
// 使用 for...of 遍历数组
for (let v of names) {
console.log(v);
}
let iterater = names[Symbol.iterator]();
console.log(iterater.next());
console.log(iterater.next());
console.log(iterater.next());
console.log(iterater.next());
迭代器自定义遍历数组
const banji = {
name: '一班',
stus: [
'ming',
'hong',
'liang',
'tian'
],
[Symbol.iterator]() {
// 索引变量
let index = 0;
let that = this;
return {
next: function() {
if (index < that.stus.length) {
const result = {
value: that.stus[index],
done: false
};
index++;
return result;
} else {
return {
value: '',
done: true
}
}
}
};
}
}
for (let v of banji) {
console.log(v);
}
生成器
// 生成器其实就是一个特殊的函数
// 异步编程 纯回调函数 node fs ajax mongodb
// yield 函数代码的分隔符
function* gen() {
yield '一直没有耳朵';
yield '一致没有尾巴';
yield '真奇怪';
};
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// 遍历
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 th = yield 333;
console.log(th);
}
// 执行获取迭代器对象
let iterator = gen('aaa');
console.log(iterator.next());
console.log(iterator.next('bbb'));
console.log(iterator.next('ccc'));
console.log(iterator.next('ddd'));
aaa
111
bbb
222
ccc
333
ddd
undefined
生成器函数实例
1s后控制台输出 111 2s 后输出222 3s后输出333
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() {
setTimeout(() => {
let data = '用户数据';
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.log(goods);
}
let iterator = gen();
iterator.next();```