let关键字
1.变量不能重复声明
3.块级作用域
2.不存在变量提升
4.不影响作用域链
const关键字
1.一定要赋初始值
2.一般常量使用大写
3.常量的值不能修改
4.块级作用域
5.对于数组和对象的元素修改,不算做对常量的修改,不会报错
解构赋值
数组的结构
const f3 = ['1','2',3] let [xiao,liu,zhao] = f3; console.log(xiao)对象的解构
const f3 = {name:'xiaoming',age:23, foo:function(){}} let {name, foo} = f3; console.log(name) foo();
模板字符串
ES6 引入了声明字符串的方式``;
1.内容中可以直接出现换行符
2.变量拼接
let lovest = 'hello'
let world = 'world'
let out = `${lovest}${world}`
let out = `${hello+world}`
简化对象写法
允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
let name = '尚硅谷'
let change = function(){
console.log('change')
}
const school = {
name,
change,
improve: function(){
console.log("我们可以提高你的技能")
},
improve1(){
console.log("简洁的方法")
}
}
console.log(school)
箭头函数
原始函数
let fn = function(){}
箭头函数
let fn = (a,b) = >{
return a + b;
}
特性:
1.this是静态的,this始终指向函数声明时所在作用域下的this的值
2.不能作为构造实例化对象
3.不能使用arguments变量
4.箭头函数的简写
1.省略小括号,当形参有且只有一个的时候
2.省略花括号,当代码体只有一条语句的时候,此时return必须省略,而且
语句的执行结果就是函数的返回值
适合场景:与this无关的回调,定时器,数组的方法回调
不适合场景:与this有关的回调,比如事件回调,对象的方法
函数参数赋初始值
function add(a, b, c){
return a + b + c;
}
function add(a, b, c=10){
return a + b +c;
}
与解构赋值结合
function connect({host, username, password, port=2203}){
}
connect({
host: 'localhost',
username: 'root',
password: 'root',
port: 3306
})
rest参数
ES6 引用 rest 参数,用于获取函数的实参用来代替 arguments
ES5 获取实参的方式
function date(){
//Arguments { 0: "白芷", 1: "小明", 2: "张三", … } 对象
console.log(arguments)
}
date('白芷','小明','张三')
ES6 获取参数
function date(...args){
//Array(3) [ "白芷", "小明", "张三" ]
console.log(args)
}
date('白芷','小明','张三')
扩展运算符
... 扩展运算符能将 数组 转换为逗号分隔的 参数序列
const tfboys = ['易烊', '五湖', 'gg'];
function chunwan(){
//Arguments { 0: "易烊", 1: "五湖", 2: "gg", … }
console.log(arguments)
}
chunwan(...tfboys);
使用:
数组的合并
const kuaizi = ['1', 2];
const fenghuang = ['3', '4'];
const c = kuaizi.concat(fenghuang)
const d = [...kuaizi, ...fenghuang]
console.log(c)
console.log(d)
数组的克隆
const fenghuang = ['3', '4'];
const d = [...fenghuang]
将伪数组转为真正的数组
const divs = document.querySelectorAll("div");
console.log(divs)//NodeList [ div#viewport, div#b]
const divArr = [...divs]; //Array [ div#viewport, div#b ]
console.log(divArr)
Symbol 基本使用
创建Symbol
let s = Symbol();
let s2 = Symbol('张三');
let s4 = Symbol.for('李四')
不能与其他数据进行运算
//USONB you are so niubility
//u undefined
//s string symbol
//o object
//n null number
//b boolean
symbol使用
给对象添加属性和方法,是独一无二的
let game = {
down: function(){
console.log('game down')
}
}
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
}
game[methods.up] = function(){
console.log('up')
}
game[methods.down] = function(){
console.log('down')
}
console.log(game.down()) //game down
console.log(game[methods.down]()) //down
迭代器Iterator
Iterator是对象的属性
ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
原生具备iterator接口的数据
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
const banji = {
name: '一班',
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator]: function () {
let index = 0;
const _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)
}
生成器Generator
其实是一个特殊的函数
异步编程,纯回调函数,node fs ajax mongodb
function* gen() {
console.log(111)
yield '一只没有耳朵';
console.log(222)
yield '一只没有尾部';
console.log(333)
yield '真奇怪'
}
let iterator = gen();
console.log(iterator)
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
生成器函数参数
function * gen(arg){
console.log(arg)
let one = yield 111;
console.log(one)
console.log(123)
}
let iterator = gen('aaa');
console.log(iterator.next(666))
console.log(iterator.next("333"))
//异步编程 文件操作 网络操作 数据库操作
//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() {
setTimeout(() => {
let data = '用户数据'
iterator.next(data);
}, 1000);
}
function getOrders(userData) {
console.log(userData)
setTimeout(() => {
let data = '订单数据'
iterator.next(data)
}, 1000);
}
function getGoods(orderData) {
console.log(orderData);
setTimeout(() => {
let data = '商品数据'
// iterator.next();
console.log(iterator.next())
}, 1000);
}
function* gen() {
let userData = yield getUsers();
let orderData = yield getOrders(userData);
let d = yield getGoods(orderData);
console.log(d)
}
let iterator = gen();
iterator.next();
Promise异步编程
语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
const p = new Promise(function (resolve, reject) {
setTimeout(() => {
// let data = '数据库中的用户数据'
//resolve(data) 将状态修改为成功
let data = '获取数据失败'
reject(data); //将状态修改为失败
}, 1000);
})
//第一个回调函数状态为成功时调用,失败则调用第二个回调函数
p.then(function (value) {
console.log(value)
}, function (reason) {
console.log(reason)
})
//读取文件
const fs = require('fs')
const p = new Promise(function (resolve, reject) {
fs.readFile('./test1.txt', (err, data) => {
//如果失败,则抛出错误
if (err) reject(err);
resolve(data)
})
})
p.then(function(value){
console.log(value)
},function(reason){
console.log("读取失败")
})
//封装 ajax
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.apiopen.top/getJoke");
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.response)
}
}
}
})
p.then(function (value) {
console.log(value)
}, function (reason) {
console.error(reason)
})
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据')
}, 1000)
})
//调用then方法 then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
//1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值对对象的成功的值
const result = p.then(value => {
console.log(value)
//1.非promise类型的属性
// return 1111;
//2.是promise对象,promise返回的值就是result的值
return new Promise((resolve, reject)=>{
resolve('ok')
})
//3.抛出错误
throw '出错啦';
}, reason => {
console.warn(reason)
})
console.log(result)
//链式调用
p.then(value=>{
}).then(value=>{
})
const fs = require('fs')
// //读取文件
// fs.readFile('./test.txt', (err1, data1) => {
// //根据读取的文件再读取文件
// fs.readFile('./test1.txt', (err1, data2) => {
// let result = data1 + data2;
// console.log(result.toString())
// })
// })
//使用promise实现,解决回调地狱问题
const p = new Promise((resolve, reject) => {
fs.readFile('./test.txt', (err, data) => {
resolve(data);
})
})
p.then(value => {
//promise的状态就是p.then返回的状态
return new Promise((resolve, reject) => {
fs.readFile('./test1.txt', (err, data) => {
resolve([value, data]);
})
})
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile('./test2.txt', (err, data) => {
value.push(data)
resolve(data);
})
})
})
Set
ES6提供了新的数据结构Set。它类似于数组,但成员的值是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for (let v of sets)进行遍历
//创建一个集合
let s = new Set();
let s2 = new Set([1, 2, 3, 1, 2])
//类型object
console.log(s, typeof s)
//元素个数
console.log(s2.size)
//添加元素
s2.add('2')
//删除元素
s2.delete(2)
//是否有
console.log(s2.has(2))
console.log(s2)
// s2.clear();
for(let v of s2){
console.log(v)
}
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
let arr2 = [4, 5, 6, 5, 6]
//1数组去重
// let result = [...new Set(arr)];
// console.log(result)
//交集
// let s2 = new Set(arr2);
// let result = [...new Set(arr)].filter(item => s2.has(item))
// console.log(result)
//并集
let union = [...new Set([...arr, ...arr2])];
console.log(union)
//差集
let s2 = new Set(arr2);
let diff = [...new Set(arr)].filter(item => !(s2.has(item)))
console.log(diff)
Map
ES6 提供了Map数据结构,它类型于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象) 都可以当作键,Map也实现了iterator 接口,所以可以使用扩展运算符和for…of进行遍历 map的属性和方法
let m = new Map()
m.set("name", 'xiaoming')
m.set("change", function () {
console.log(change)
})
let key = {
school : 'clsnull'
}
m.set(key, ['北京','上海'])
// console.log(m.size)
// m.delete(key)
console.log(m.get(key))
console.log(m.has(key))
console.log(m.clear())
console.log(m)
for (const v of m) {
console.log(v)//[k,v]
}
class类
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log('我可以打电话')
}
let huawei = new Phone('华为', 3000);
console.log(huawei)
huawei.call();
class Phone {
//构造方法 名字不能修改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//方法必须使用该语法,不能使用ES5的对象完整形式
call() {
console.log(this)
console.log('我可以打电话!!')
}
}
let mi = new Phone('xiaomi', '1999')
console.log(mi)
mi.call();
静态成员
// function Phone() {
// }
// //下面两个是属于函数对象的,这样的属性称为静态成员
// Phone.name = '手机';
// Phone.change = function () {
// console.log("我可以改变")
// }
// console.log(Phone.name)
// //实例对象没有函数对象(构造函数对象)上的属性和方法的
// let nokia = new Phone();
// //实例对象与原型对象是相通的
// Phone.prototype.size = '5.5inch'
// console.log(nokia.name) //undefined
// console.log(nokia.size) //5.5inch
//+++++++++++++++++++++++++++++++++++++++++++++++++++
class Phone {
//静态成员
static name = '手机';
static change() {
console.log('我可以改变世界')
}
}
let nokia = new Phone();
//不属性实例对象
console.log(nokia.name); // undefined
//属于类
console.log(Phone.name); // '手机'
**ES5类的继承 **
// 对象继承
// es5写法
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log("我可以打电话");
}
//智能手机
function SmartPhone(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;
//声明子类的方法
SmartPhone.prototype.photo = function () {
console.log('我可以拍照')
}
const mi = new SmartPhone('小米', 1000, '黑色', ' 5.5inch')
console.log(mi)
ES6继承
class Phone {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
call() {
console.log("我可以打电话")
}
}
class SmartPhone extends Phone {
constructor(brand, price, color, size) {
super(brand, price)
this.color = color;
this.size = size;
}
photo() {
console.log("我可以拍照")
}
call() {
console.log("对父类的重写我可以进行视频通话")
}
}
let mi = new SmartPhone("小米", 3222, "红色", '3.4inch');
console.log(mi)
mi.call(); //对父类的重写我可以进行视频通话
getter和setter
//get 和 set
class Phone {
get price() {
console.log("价格的属性被读取了");
return 'price'
}
set price(newVal){
console.log("价格属性被修改了")
}
}
let s = new Phone();
s.price = 'free'
模块化
模块化的好处
- 防止命名冲突
- 代码利用
- 高维护性
模块化规范产品
- CommonJs => NodeJs、Browserify
- AMD => requireJS
- CMD => seaJ
模块化语法
模块化功能主要由两个命令构成:export和import
- export 命令用于规定模块的对外接口
- import 命令用于输入其他模块提供的功能
基本使用
// m1.js
//分别暴露
export let school = 'java'
export function teach() {
console.log("thach")
}
//统一暴露
let school = 'java'
function teach() {
console.log("thach")
}
export {
school,
teach
}
//默认暴露
export default {
school: 'sa',
change: function () {
console.log('change')
}
}
<script type="module">
import * as m1 from './m1.js'
console.log(m1)
</script>
//1.通用的导入方式
// import * as m1 from './m1.js'
// import * as m2 from './m2.js'
// import * as m3 from './m3.js'
// console.log(m1)
// console.log(m2)
// console.log(m3)
// m3.default.change()
//2.解构赋值形式
// import { school, teach } from './m1.js'
// import { school as s2, findJ } from './m2.js'
// import { default as m3 } from './m3.js'
// console.log(school)
// console.log(s2)
// console.log(teach)
// console.log(m3)
//3.简便形式,针对默认暴露
import m3 from './m3.js'
console.log(m3)
async和await
async和await两种语法结合可以让异步代码像同步代码一样
async函数
async函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定
//async 函数 返回的是promise async function fn() { //返回的不是一个promise对象,则这个结果就是一个成功的promise对象 // return 1; // throw new Error("出错了") //返回的结果是一个失败的promise //返回的结果如果是一个promise对象 //如果这个promise对象成功了,则fn()也是成功的,返回的值就是promise成功的值 return new Promise((resolve, reject) => { resolve("成功的数据 ") reject("失败") }) } const result = fn(); console.log(result)
await表达式
- await 必须写在async函数中
- await 右侧的表达式一般为promise对象
- await 返回的是promise成功的值
- await 的promise失败了,就会抛出异常,需要通过try-catch捕获处理
const p = new Promise((resolve, reject) => {
// resolve("成功的值 ")
reject("失败")
})
async function fn() {
try {
let result = await p;
console.log(result)
} catch (e) {
console.log(e)
}
}
fn();
async和await
const fs = require("fs");
function readOne() {
return new Promise((resolve, reject) => {
fs.readFile('./1.txt', (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
function readTwo() {
return new Promise((resolve, reject) => {
fs.readFile('./2.txt', (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
function readThree() {
return new Promise((resolve, reject) => {
fs.readFile('./3.txt', (err, data) => {
if (err) reject(err)
resolve(data)
})
setTimeout(()=>{},100000)
})
}
async function main() {
let three = await readThree();
let two = await readTwo();
let one = await readOne();
console.log(three.toString())
console.log(one.toString())
console.log(two.toString())
}
main();
function sendAjax(url) {
return new Promise((resolve, reject) => {
const x = new XMLHttpRequest();
x.open('GET', url);
x.send();
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
resolve(x.response)
} else {
reject(x.status)
}
}
}
})
}
async function main() {
let result = await sendAjax("https://api.apiopen.top/getJoke")
console.log(result)
}
let result = sendAjax("https://api.apiopen.top/getJoke")
result.then(value => {
console.log(value)
})
对象展开和Rest
Rest参数与spread扩展运算符在es6中已经引入,不过es6只针对数组,
在es9中为对象提供了像数组一样的rest参数和扩展运算符
function connect({ host, port, ...user }) {
console.log(host)
console.log(port)
console.log(user)
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
})
//对象扩展运算符
const skillOne = {
q: '天音波'
}
const skillTwo = {
w: '金钟罩'
}
const mangseng = {
...skillOne,
...skillTwo,
e: '天雷破'
}
console.log(mangseng)
文档信息
- 本文作者:clsnull
- 本文链接:https://clsnull.github.io/2021/05/05/ES6%E7%AC%94%E8%AE%B0/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)