一、Symbol
ES6 引入了一种新的原始数据类型Symbol表示独一无二的值,它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型
js的其中类型速记:usonb you are so niubility
u:undefined s:string symbol symol o:object n:null number
1.1 Symbol的特点
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
1.2 创建Symbol的方式有两种
1.函数法
let s = Symbol()
console.log(s, typeof s) // Symbol() 'symbol'
// 这里的Symbol是个函数
let s2 = Symbol('ES6') // 单引号里面的内容用作 描述 类似身份证的姓名 可以和其他Symbol重复
let s3 = Symbol('ES6')
// Symbol就像身份证一样 ES6可以看做是姓名 而Symbol的地址可以看做是身份证号 姓名可以重复 但身份证号不能重复 所以返回false
console.log(s2 === s3) // false 描述信息相同时返回的依旧是false
2.函数对象法
// 这里的Symbol是对象 函数对象
let s4 = Symbol.for('ES6')
let s5 = Symbol.for('ES6')
console.log(s4, typeof s4); // Symbol(ES6) 'symbol'
console.log(s4 === s5) // true 描述信息相同时返回true,不同返回false
这两种方法的区别在于,你调用n个Symbol()会得到n不一样的值,但是调用Symbol.for()会得到相同的值,另外函数法的描述信息相同时返回的依旧是false,而函数对象法描述信息相同时返回true,不同返回false。
值得注意的是:
Symbol类型不能和其他数据进行运算
1.3 Symbol的应用场景
向对象中添加方法
// 向对象中添加方法 up down
let game = {}
// 声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
}
game[methods.up] = function () { // 添加up方法
console.log("我可以改变形状");
}
game[methods.down] = function () { // 添加down方法
console.log("我可以快速下降!");
}
console.log(game); // 可以把Symbol理解成一个唯一的字符串 输出显示的是Symbol 但实际上是一个字符串
// 另一种添加方法
let youxi = {
name: "狼人杀",
[Symbol('say')]: function () {
console.log("我可以发言");
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
}
console.log(youxi);
Symbol内置方法:略
二、迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作,Iterator接口就是对象里面的一个属性,这个属性的名字叫做Symbol.iterator
1)ES6 创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
2)原生具备Iterator接口的数据(可用for…of遍历) Array Arguments Set Map String TypedArray NodeList
3)工作原理
a 创建一个指针对象,指向当前数据结构的起始位置
b 第一次调用对象的next方法 指针自动指向数据结构的第一个成员
c 接下来不断调用next方法 指针一直往后移动 直到指向最后一个成员
d 每调用next方法返回一个包含value的done属性的对象
注:需要自定义遍历数据的时候,要想到迭代器
// 声明一个数组
const xiyouji = ['唐僧', '孙猴子', '猪八盖', '杀生']
// 使用for...of遍历数组
for (let v of xiyouji) {
console.log(v); // 唐僧 孙猴子 猪八盖 杀生
}
三、生成器
3.1 生成器基本使用
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
异步编程 纯回调函数 node fs ajax mongodb
yield 是函数代码的分隔符
function* gen() {
// yield 是函数代码的分隔符
console.log(111);
yield '一只没有耳朵';
console.log(222);
yield '一只没有尾巴';
console.log(333);
yield '真奇怪';
console.log(444);
}
let iterator = gen()
console.log(iterator); // 输出生成器
// 调用next函数执行生成器里面的内容
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// 遍历
for (const v of gen()) {
console.log(v);
}
异步编程:文件操作,网络操作(ajax,request),数据库操作
3.2生成器使用案例
需求: 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()
}, 1000)
}
function three() {
setTimeout(() => {
console.log(333);
}, 1000)
}
function* gen() {
yield one()
yield two()
yield three()
}
// 调用生成器函数
let iterator = gen()
iterator.next()
四、Promise
4.1 Promise基本使用
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- Promise构造函数:Promise(excutor){}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
// 实例化 Promise 对象
const p = new Promise(function (resolve, reject) {
setTimeout(function () {
// 数据获取成功调用resolve函数
// let data = '数据库中的用户数据'
// resolve(data)
// 数据获取失败调用reject函数
// let err = '数据读取失败'
// reject(err)
}, 1000);
})
// 调用promise对象的then方法
p.then(function (value) {
console.log(value);
}, function (reason) {
console.error(reason);
})
4.2 Promise发送Ajax请求
// 接口地址 https://api.apiopen.top/getJoke
// 1. 创建对象
const xhr = new XMLHttpRequest()
// 2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJoke")
// 3. 发送
xhr.send()
// 4. 绑定事件,处理响应结果
xhr.onreadystatechange = function () {
// 判断
if (xhr.readyState === 4) {
// 判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status < 300) {
// 表示成功
console.log(xhr.response);
} else {
// 如果失败
console.error(xhr.status);
}
}
}
4.3 Promise-then方法
then方法会根据promise对象的执行结果来执行不同的回调函数。
调用then方法, then方法的回调结果是Promise对象,对象状态由回调函数的执行结果决定。
如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象的成功返回值。
如果回调函数返回的结果是promise类型的属性,则根据返回的是resolve还是reject来判断状态是成功还是失败。
// 创建promise对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据')
}, 1000)
})
// 调用then方法
const result = p.then(value => {
console.log(value);
// 1. 非promise类型的属性
// return 'iloveu'
// 2. 是promise对象
// return new Promise((resolve, reject) => {
// resolve('ok')
// // reject('error')
// })
// 3. 抛出错误
// throw new Error('出错拉!')
}, reason => {
console.warn(reason);
})
console.log(result);
4.4 Promise链式-读取多个文件
// 引入fs模块
const fs = require("fs");
const p = new Promise((resolve, reject) => {
fs.readFile("./resources/markdown1.md", (err, data) => {
resolve(data);
});
});
p.then((value) => {
console.log(value.toString());
return new Promise((resolve, reject) => {
fs.readFile("./resources/markdown2.md", (err, data) => {
resolve([value, data]);
});
});
})
.then((value) => {
return new Promise((resolve, reject) => {
fs.readFile("./resources/markdown3.md", (err, data) => {
value.push(data);
resolve(value);
});
});
})
.then((value) => {
console.log(value.join("\r\n"));
});