ES6 入门第四章 (Symbol、迭代器 Iterator、生成器函数)

ES6 入门第四章

Symbol基本使用

ES6 引入了一种新的原始数据类型Symbol。表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol 特点

1) Symbol 的值是唯一的,用来解决命名冲突的问题

2) Symbol值不能与其他数据进行运算

3) Symbol定义的对象属性不能使用 for…in 循环遍历,但是可以使用Reflect。ownKeys 来获取对象的所有键名

  1. 创建Symbol
//创建Symbol
let s = Symbol();
console.log(s, typeof s);

在这里插入图片描述

let s2 = Symbol('人性的弱点');
let s3 = Symbol('人性的弱点');
console.log(s2 === s3);

在这里插入图片描述
2. Symbol.for 创建

//Symbol.for 创建
let s4 = Symbol.for('狼道');
console.log(s4,typeof s4);

在这里插入图片描述

let s4 = Symbol.for('狼道');
let s5 = Symbol.for('狼道');
console.log(s4 === s5);

在这里插入图片描述
注意事项

不能与其他数据进行运算

//不能与其他数据进行运算
let s = Symbol();
let result = s + 100;
//let result = s > 100;
//let result = s +'100';

在这里插入图片描述
Symbol 创建对象属性

let youxi = {
name:"狼人杀",
[Symbol('say')]: function(){
	console.log("我可以发言")
},
[Symbol('zibao')]: function(){
	console.log("我可以自爆")
}
}
console.log(youxi);

在这里插入图片描述

Symbol 内置值

除了定义自己使用的 Symbol 值以外,ES6 还提供了11个内置的Symbol值,指向语言内部使用的方法。

Symbol.hasInstance当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开
Symbol.unscopables该对象指定了使用with 关键字时,哪些属性会被 with环境排除
Symbol.match当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值
Symbol.replace当该对象被 str.replace(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值
Symbol.search当该对象被 str.search(myObject)方法调用时,会返回该方法的返回值
Symbol.split当该对象 str.split(myObject)方法调用时,会返回该方法的返回值
Symbol.iterator对象进行for…of循环时,会调用Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
Symbol.toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol.species创建衍生对象时,会使用该属性
  1. Symbol.hasInstance
class Person{
static [Symbol.hasInstance](param){
	console.log(param);
	console.log("我被用来检测类型了")
 }
}
			
let o = {};
console.log(o instanceof Person);

在这里插入图片描述

class Person{
static [Symbol.hasInstance](param){
	console.log(param);
	console.log("我被用来检测类型了")
	return true;
 }
}
			
let o = {};
console.log(o instanceof Person);

在这里插入图片描述
Symbol.hasInstance 可以自己控制类型检测

  1. Symbol.isConcatSpreadable
const arr = [1,2,3];
const arr2 = [4,5,6];
console.log(arr.concat(arr2));

在这里插入图片描述

const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));

在这里插入图片描述

迭代器 Iterator

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口(对象里面的属性),就可以完成遍历操作。

1)ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

2)原生具备 Iterator 接口的数据(可用for of 遍历)

​ a)Array

​ b)Arguments

​ c)Set

​ d)Map

​ e)String

​ f)TypedArray

​ g)NodeList

for…of 中的 of 前面的变量保存的是键值

//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
//使用 for...of 遍历数组
for(let v of xiyou){
	console.log(v);
}

在这里插入图片描述
for…in 中的 in 前面的变量保存的是键名

//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
//使用 for...in 遍历数组
for(let v in xiyou){
	console.log(v);
}

在这里插入图片描述
3)工作原理

​ a)创建一个指针对象,指向当前数据结构的起始位置

​ b)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员

​ c)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员

注:需要自定义遍历数据的时候,要得到迭代器。

const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
console.log(iterator);

在这里插入图片描述

const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());

在这里插入图片描述

let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(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.iterator](){
	//索引变量
	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};
			}
		}
	};
}
}
			
//遍历这个对象
for(let v of banji){
	console.log(v);
}

在这里插入图片描述

生成器

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完成不同。

function * gen(){
	yield '一只没有耳朵';
	yield '一只没有尾巴';
}
//生成器其实就是一个特殊的函数
//异步编程 纯回调函数 node fs ajax mongodb
function * gen(){
	console.log("hello generator");
}
let iterator = gen();
console.log(iterator);

在这里插入图片描述
如果想gen()里面的内容运行,则需要next():

function * gen(){
	console.log("hello generator");
}
let iterator = gen();
iterator.next();

在这里插入图片描述
yield 函数代码的分隔符

//函数代码的分隔符
function * gen(){
	console.log(111);
	yield '一只没有耳朵';
	console.log(222);
	yield '一只没有尾巴';
	console.log(333);
	yield '真奇怪';
	console.log(444);
}
let iterator = gen();
iterator.next();
iterator.next();
iterator.next();
iterator.next();

由上面的代码,得知:yield将gen()里面分成了四段,由next来控制输出几段
在这里插入图片描述
我使用了四次next,则四段都输出了。

遍历

//遍历
function * gen(){
	yield '一只没有耳朵';

	yield '一只没有尾巴';

	yield '真奇怪';
	
}
			
let iterator = gen();

//遍历
for(let v of gen()){
	console.log(v);
}

在这里插入图片描述

function * gen(){
	yield '一只没有耳朵';

	yield '一只没有尾巴';

	yield '真奇怪';
	
}
			
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

在这里插入图片描述
done表示循环是否结束。

生成器函数参数

function * gen(arg){
	console.log(arg);
	yield 111;
	yield 222;
	yield 333;
}
//执行获取迭代器对象
let iterator = gen('AAA');

上面代码将不会输出gen()里面 的内容,需要加上next,才有输出。

function * gen(arg){
	console.log(arg);
	yield 111;
	yield 222;
	yield 333;
}
//执行获取迭代器对象
let iterator = gen('AAA');
console.log(iterator.next());

在这里插入图片描述

在这里插入图片描述

生成器函数实例

实例1:

异步编程: 1s 后控制台输出 111 2s后输出 222 3s后输出 333
使用setTimeout实现

//回调地狱
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();

在这里插入图片描述
实例2:模拟获取 用户数据 订单数据 商品数据

function getUsers(){
	setTimeout(() => {
		let data = '用户数据';
		//调用 next 方法,并且将数据传入
		iterator.next(data);
	},1000)
}
			
function getOrders(){
	setTimeout(() => {
		let data = '订单数据';
		iterator.next(data);
	},1000)
}
			
function getGoods(){
	setTimeout(() => {
		let 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();

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值