ES6

es6

let变量

//let   声明变量
let a, b, c;
// 1.变量不能重复声明
let strs = 'new';
// let strs = 'hh';

// 2.块级作用域 函数 if for,但不影响作用连的效果
{
let name = '张三';
var school = 'keshi';
}
console.log(school);
console.log(name)

// 3.不存在变量提升
console.log(song)
// let song = 'hello';

const常量

//声明常量
const SCHOOL = '尚硅谷';

//1.一定要赋值
// cosnt a;
//2.一般通常大写(潜规则)
// const SCHOOL = '';
//3. 常量的值不能更改
// SCHOOL = 'shaolin';
// 4.作用域
{
const NAMES = "hello";
}
// 5.对于数组和对象的元素修改,不算对常量的修改,不会报错
const TEAM = ['uzi', 'yly'];
TEAM.push('ne');
console.log(TEAM);

变量的赋值

// 变量的结构赋值
// 1.数组结构
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝'];
let [xiao, liu, zhao, song] = F4;
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);
// 2.对象的结构
const bao = {
name: '宋小宝',
age: '不详',
xiaopin: function() {
console.log('我能演小品');
}
}
// let { name, age, xiaopin } = bao;
// console.log(name)
// console.log(age);
// xiaopin();

let { xiaopin } = bao;
xiaopin();

模板字符转

// 模板字符转
// 1.内容中可以直接出现换行符
let strs = `看我
换行`;
console.log(strs);

// 2.变量拼接
let lovest = '苏炳添';
let out = `${lovest}是短跑冠军`;
console.log(out);

简化对象写法

// 大括号里面可以直接写入变量和函数,作为对象的属性和方法
let name = '尚硅谷';
let chang = () => {
console.log('我可以改变你');
}

const SCHOOL = {
name,
chang,
// 把function省略了
defau() {
console.log('我可以提高你的技能');
}
}
console.log(SCHOOL);

箭头函数

// 箭头函数( => ) 定义函数
//声明一个函数
// let fn = function() {

// }
// let fn = (a, b) => {
// return a + b;
// }
// 调用函数
// let result = fn(2, 4);
// console.log(result);

// 1.this是静态的. this 始终是指向函数声明所在的作用域下的 this 值
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
const SCHOOL = {
name: "VUE"
}
window.name = "尚硅谷";
// 直接调用
getName();
getName2();
// call 方法调用
getName.call(SCHOOL);
getName2.call(SCHOOL);

// 2. 不能做构造函数实例化
// let Person = (name, age) => {
// this.name = name;
// this.age = age;
// }
let Person = function(name, age) {
this.name = name;
this.age = age;
}
let me = new Person("xiao", 20);
console.log(me);

// 3.不能使用 arguments 变量
// let fn = () => {
// console.log(arguments);
// }
// function fn() {
// console.log(arguments);
// }
// fn(1, 2)

// 4. 箭头函数的简写
// 1). 省略小括号,当形参有且只有一个的时候
let add = n => {
return n + n;
}
console.log(add(2));
// 2).省略花括号,当代码体只有一条语句的时候,此时 return 也必须省略.
let pow = n => n * n;
console.log(pow(9));
let pows = (n, m) => n * m;
console.log(pows(38, 29))

函数默认值

// 函数参数默认值
// 1. 形参初始值, 具有默认值的参数,一般位置靠后(潜规则)
function add(a, b, c = 10) {
return a + b + c;
}
let result = add(1, 2);
console.log(result);

// 2.与解构赋值结合
function connsct({ host = 183, username, password, port }) {
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}

connsct({
// host: "atguigu.com",
username: "root",
password: "root",
port: 13306
})

rest 参数

// 引用 rest 参数
function date(...ages) {
console.log(ages);
}
date(2, 4, 7, 5, 3);

// rest 参数必须放到最后
function fn(a, b, ...ages) {
console.log(a, b, ages);
}
fn(1, 2, 3, 4, 5, 6, 7, 8)

扩展运算符

//  【...】 扩展运算符 数组 转换为 参数
const ARR = ['易烊千玺', '王源', '王俊凯'];
// => '易烊千玺', '王源', '王俊凯'

function chunwan() {
console.log(arguments);
}
chunwan(...ARR);
//  1.数组合并
const kuaizi = ['王太利', '肖央'];
const fenghuang = ['曾毅', '玲花'];
// 普通合并数组
// const zuixuan = kuaizi.concat(fenghuang);

const zuixuan = [...kuaizi, ...fenghuang];
console.log(zuixuan);

// 2. 将伪数组 转换为真正的数组
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);

Map对象

​ ES6 提供了 Map 数据结构. 它类似于对象, 也是键值对的集合.但是”健”的范围不限于字符串. 各种类型的值(包括对象都可以当作健.Map 也实现了 iterator 接口, 所以可以使用[扩展月算符] 和 [for…of] 进行遍历. Map的属性和方法;

name function
size 返回Map的元素个数
set 增加一个新的元素
get 返回键名对象的键值
has 检测Map中是否包含某个元素, 返回 boolean值
clear 清空集合, 返回undefined
//	创建一个空 map
let m = new map();
// 创建一个非空 map

Map数组的使用

//  声明 Map
let m = new Map();
// 添加元素 set(key,value);
m.set('names', '尚硅谷');
m.set('chang', () => {
console.log("我可以改变你")
});
let key = {
school: 'ATGUIGU'
};
// 健是 一个对象, 值是一个数组
m.set(key, ['上海', '北京', '深圳']);
// size
// console.log(m.size);

// 删除
// m.delete('names');

// 获取
// console.log(m.get('chang'))
// console.log(m)

// 清空
// m.clear();

// 遍历
for (let v of m) {
// 打印的是数组
console.log(v);
}

class类

​ ES6提供了更接近传统语言的写法, 引入了 class (类) 这个概念,作为对象的模板. 通过class关键字, 可以定义类.基本上, ES6 的class 可以看作只是一个语法糖, 它的绝大部分功能, ES5 都可以做到, 新的class 写法只是让对象原型更清晰. 更像面向对象编程语法而已.

知识点:

class 声明类
constructor 定义构造函数初始化
extends 继承父类
super 调用父级构造方法
static 定义静态方法和属性
父类方法可以重写

class使用

//  ES5 语法实现
{
// 手机
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}

// 添加方法
Phone.prototype.call = function() {
console.log('我可以打电话');
}

// 实例化对象
let Huawei = new Phone('华为', 5999);
Huawei.call();
console.log(Huawei);
}

// ES6 class 语法实现
class Phone {
// 构造方法 ,名字不能修改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}

// 方法必须使用该语法, 不能使用 ES5 的对象完整形态
call() {
console.log('我可以打电话')
}
}

let onePlus = new Phone('小米', 2999);
onePlus.call();
console.log(onePlus);

static

// function Phone() {

// }
// // 数据函数对象的 不属于实例对象
// Phone.name = '手机';
// Phone.change = function() {
// console.log('我可以改变世界');
// }
// Phone.prototype.size = '5.5inch';

// let nokia = new Phone();
// console.log(nokia.name); // 访问不到
// console.log(nokia.size); // 访问成功

class Phone {
// 静态属性
static name = '手机';
static change() {
console.log('我可以改变世界');
}
}
let nokia = new Phone();
console.log(nokia.name);
console.log(Phone.name);
Phone.change();

使用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.photo = function() {
console.log('我可以拍照');
}

SmartPhone.prototype.playGame = function() {
console.log("我可以玩游戏");
}

const chuizi = new SmartPhone('锤子', 2499, 'black', '5.5inch');

console.log(chuizi);
chuizi.playGame();
chuizi.photo();

使用ES6构造函数来实现继承

//  创建父类  普通手机
class Phone {
constructor(brand, price) {
this.brand = brand;
this.price = price;
};
// 方法
call() {
console.log("我可以打电话");
}
}
let p = new Phone('mi', 2999);
console.log(p);
p.call();
console.log('-------子类---------');
// 创建子类 智能手机
// extends 是关键字 证明 Phone 是父类
class SmartPhone extends Phone {
constructor(brand, price, color, size) {
// 子类调用父类的方法 super
super(brand, price);
this.color = color;
this.size = size;
}
playGame() {
console.log('我可以玩游戏');
}
photo() {
console.log('我可以拍照');
}
}

const chuzi = new SmartPhone('锤子', 9999, 'black', '5.5inch');
console.log(chuzi);
chuzi.call();
chuzi.playGame();
chuzi.photo();

class 中 get 和 set

//  class 中的 get 和 set
class Phone {
get price() {
console.log('价格被读取了');
return 'iloveyou';
}

set price(newval) {
console.log('价格被修改了');
console.log(newval);
}
}

// 实例化对象
let s = new Phone();
console.log(s.price);
// console.log()
s.price = 1;

API

Set数组

//  声明一个集合
let s = new Set();
// 会把相同的给 去掉
let s2 = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿']);

// 元素个数
// console.log(s2.size);
// 添加元素
// s2.add('喜事儿');
// 删除元素
// s2.delete("坏事儿");
// 检测 有返回 true 没有返回 false
// console.log(s2.has('好事儿'));
// 清空
// s2.clear();
for (let v of s2) {
console.log(v);
}

Set使用

let arr = [1, 2, 3, 3, 5, 3, 7, 6, 3, 8, 3];
// 1.数组去重
// let result = [...new Set(arr)];
// 2.交集
let arr2 = [3, 4, 5, 6, 7, 5]; // .filter 循环数组
// let result = [...new Set(arr)].filter(item => {
// let s2 = new Set(arr2);
// // return s2.has(item) ? true : false;
// if (s2.has(item)) {
// return true;
// } else {
// return false;
// }
// });
// 简化
// let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));

// 3.并集
// let union = [...new Set([...arr, ...arr2])];
// console.log(union);
// 4.差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);

Symbol数据类型

​ Symbol 是类似于字符转的 数据类型

  1. Symbol的值是唯一的, 用来解决命名冲突问题
  2. Symblo 值不能与其他数据类型进行运算
  3. Symbol 定义的对象属性不能只用 fot..in 循环遍历, 但是可以使用Reflect.ownKeys来获取对象的所有健名
//  创建 Symbol, 内部实现了 唯一性
let s = Symbol("hello");
console.log(s, typeof s);
let s1 = Symbol('尚硅谷'); // 内置函数
let s2 = Symbol('尚硅谷'); //这里只是一个标志
console.log(s1 === s2); // false
// 创建一个 Symbol.for 函数对象
let s3 = Symbol.for("张三");
let s4 = Symbol.for("张三");
console.log(s3 === s4);
// 不能与其他数据进行运算

/* USONB you are so niubility
u undefined
s string symbol
o object
n null nmumber
b boolean
*/

Symbol 的使用

//  symbol 的使用场景 就是给对象添加属性和方法
// 向对象中添加 up down 方法
let game = {};
// 1. 声明对象
let methods = {
up: Symbol(),
down: Symbol()
};
// 安全且快速的添加进去
game[methods.up] = function() {
console.log('我是up');
}
game[methods.down] = function() {
console.log('我是down');
}
console.log(game);

Symbol用来做类型检测

//  Symbol 内置属性
class Person {
static[Symbol.hasInstance](param) {
console.log(param);
console.log('我被用来检测类型了');
}
};
let o = {};
console.log(o instanceof Person)

Symbol数据展开

const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
// Symbol.isConcatSpreadable] 控制数据是否可展开
// 默认值是true
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));

迭代器

​ 迭代器是一种接口, 为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口, 就可以完成遍历操作.

  1. ES6 创造了一种新遍历命令 for…of 命令, Iterator 接口主要提供for..of消费
  2. 原生具备 Iterator 接口的数据(可用 for .. of 遍历)
const arr = ['唐僧', '猪八戒', '孙悟空', '沙僧'];

let iterator = arr[Symbol.iterator]();
console.log(iterator);
// 调用迭代器
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

自定义遍历

const Ban = {
name: '终极一班',
stus: [
'小明',
'小红',
'小宁'
],
[Symbol.iterator]() {
// 索引变量
let index = 0;
return {
next: () => {
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 Ban) {
console.log(v);
}

生成器

//  生成器其实就是一个特殊函数
// 异步编程 纯回调函数 node fs ajax mongodb
// 函数代码分隔符 yield
function* fen() {
console.log(111);
yield 'one';
console.log(222)
yield 'two';
console.log(333);
yield 'three';
console.log(444);
}
let iterator = fen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log('-------------')
for (let v of fen()) {
console.log(v);
}

回调函数

// 异步编程  文件操作   网络操作(ajax, request) 数据库操作
// 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);
iterator.next();
}, 1000)
}

function* gen() {
yield one();
yield two();
yield three();
}

const iterator = gen();
iterator.next();

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.log(reason);
});
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// 如果成功了 使用 resolve方法
// resolve("用户数据");
// 如果失败了 调用 reject方法
reject("出错了");
}, 1000)
});

// 调用 then方法
p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})

处理文件的使用

const { rejects } = require('assert');
const fs = require('fs');
// 1.调用方法读取文件
// fs.readFile('./文件/xue.md', (err, data) => {
// // 如果失败, 则抛出 作物
// if (err) throw err;
// // 如果没有出错, 则输出内容
// console.log(data.toString());
// })

// 3. 使用 Promise 封装
const p = new Promise(function(resolve, reject) {
fs.readFile('./文件/xue.md', (err, data) => {
// 判断 如果失败
if (err) reject(err);
// 如果成功
resolve(data);
});
});

p.then(function(value) {
console.log(value.toString());
}, function(reason) {
console.log("读取失败!!!");
})