一、Symbol
ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
1.Symbol 创建
(1)Symbol 数据类型的特点是唯一性,即使是用同一个变量生成的值也不相等。
第一种:
let a = Symbol("a");//a为symbol的描述
let b = Symbol("a");
console.log(a === b);//false
第二种:
let s3 = Symbol.for('bb');
let s4 = Symbol.for('bb');
console.log(s3===s4) //true
(2)Symbol 数据类型不能与其他数据类型运算。
Let c = a+100;//Cannot convert a Symbol value to a number
直接报错
(3)Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。
2.Symbol内置值
ES6除了定义自己使用的Symbol值以外,还提供了11个内置的Symbol值,指向语言内部使用的方法。
1:Symbol.hasInstance:当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法。
****2:Symbol.****isConcatSpreadable:对象的Symbol.isConcatSpreadable属性等于一个bool值,表示该对象用于Array.prototype()时,是否可以展开。
3:Symbol.unscopables:该对象指定了使用with关键字时,哪些属性会被with环境排除。
4:****Symbol.match:当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
5:****Symbol.replace:当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。
6:****Symbol.search:当该对象被str.search(myObject)方法调用时,会返回该方法的返回值。
7:****Symbol.split:当该对象被str.split(myObject)方法调用时,会返回该方法的返回值。
8:****Symbol.iterator:对象进行for ... of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器。
9:****Symbol.toPrimitive:该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
10:****Symbol.toStringTag:在该对象上调用toString方法时,返回该方法的返回值。
11:****Symbol.species:创建衍生对象时,会使用该属性。
3.Symbol使用场景
let Person = {
realname: '张三',
age: 18
}
let Method = {
say: Symbol(),
play: Symbol(),
}
Person[Method.say] = () => {
console.log('会说话');
}
Person[Method.play] = () => {
console.log('打游戏');
}
const keys = Reflect.ownKeys(Person); //获得所有的key
const sysbolKeys = Object.getOwnPropertySymbols(Person); //获得symbol的keys
console.log(sysbolKeys);
Person[sysbolKeys[0]](); //调用方法 会说话
Person[sysbolKeys[1]](); //调用方法 打游戏
给对象添加方法,不予对象属性冲突。
二、迭代器
1.定义
迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作,ES6新增遍历方式for...of。原生具备lterator接口的数据有:Array,Arguments,Set,Map,String,NodeList。
2.原理
创建一个指针对象,指向数据结构的起始位置,第一次调用==next()==方法,指针自动指向数据结构第一个成员,接下来不断调用next(),指针一直往后移动,直到指向最后一个成员,没调用next()返回一个包含value和done属性的对象。
let arr = ["a","b","c"];
let myIte = arr[Symbol.iterator]();//arr本身就具备迭代器接口,拿到这个iterator接口
console.log(myIte.next());//{value: "a", done: false}
console.log(myIte.next());//{value: "b", done: false}
console.log(myIte.next());//{value: "c", done: false}
console.log(myIte.next());//{value: "undefined", done: true}
3.迭代器使用场景
遵循面向对象思想,自定义遍历数据。
const Stu = {
title: "web2209",
persons: ["张三", "李四", "王五"],
[Symbol.iterator]() {
let i = 0;
return {
next: () => {
if (i < this.persons.length) {
const Obj = { value: this.persons[i], done: false };
i++;
return Obj;
} else {
return { value: undefined, done: true };
}
}
}
}
}
const Myite = Stu[Symbol.iterator]();
console.log(Myite.next());
console.log(Myite.next());
console.log(Myite.next());
console.log(Myite.next());
// 遍历对象的值
// for(let v of Stu){
// console.log(v);
// }
三、生成器
1.定义
生成器本身是一个特殊的函数,生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同。
function * ride(num){
console.log("函数执行了...");
yield num*2;
console.log("第二步...");
yield num*4;
console.log("第三步...");
yield num*8;
console.log("函数执行end...");
}
2.生成器调用
执行生成器函数,返回的是一个迭代器对象,通过iterator.next()调用执行函数内语句,用yield 的分隔符让语句分段执行。
function * ride(num){
console.log("函数执行了...");
yield num*2;
console.log("第二步...");
yield num*4;
console.log("第三步...");
yield num*8;
console.log("函数执行end...");
}
const myride = ride(10);//生成器函数调用的时候 会生成一个迭代器对象
console.log(myride.next());
console.log(myride.next());
console.log(myride.next());
console.log(myride.next());
3.生成器传参
next('BBB')传入的参数作为上一个next方法的返回值。
function * ride(num){
let a1 = yield num*2;
console.log(a3);
let a2 = yield a1*4;
console.log(a3);
let a3 = yield a2*8;
console.log(a3);
}
const myride = ride(10);
myride.next();
console.log(myride.next(20));//a1就是20
console.log(myride.next(30));//a2就是30
console.log(myride.next(40));//a3就是40
4.生成器的应用
点击按钮,加载数据....,数据加载完成后隐藏(加载数据文字)
<body>
<p id="tip"></p>
<p id="msg"></p>
<button class="btn">查询</button>
<script>
let tip = document.getElementById('tip');
let msg = document.getElementById('msg');
let btn = document.querySelector('.btn');
function step_1(){
setTimeout(()=>{
let msg = '正在加载数据...' ;
getinfo.next(msg);
},1000)
}
function step_2(){
setTimeout(()=>{
let data = '加载成功!' ;
getinfo.next(data)
},1000)
}
function step_3(){
tip.innerHTML = '';
}
function * info(){
let mark = yield step_1();//把正在加载数据输入到页面中
tip.innerHTML = mark;
let data = yield step_2();//页面输出加载成功
msg.innerHTML = data;
yield step_3(); //清楚加载页面
//注:当代码运行到定时器时,默认把定时器内容等级向下
}
const getinfo = info();
btn.addEventListener('click',()=>{
getinfo.next();
})
</script>
版权归原作者 秃头小骡子 所有, 如有侵权,请联系我们删除。