ES6学习记录
视频-b站ES6从入门到精通系列(全23讲),开发必备,推荐必看
1. var let const区别与使用
var是一个全局变量,有变量提升,允许重名,会污染既有全局变量
let是一个局部变量,没有变量提升,不允许重名,不会污染全局变量
const是一个常量,不允许修改,只能读取,没有变量提升,不允许重名
2. 模板字符串
let htmlStr = `<ul>
<li>${name}</li>
</ul>`
// 等同于
let div.innerHtml = "<ul><li>"+name+"</li></ul>"
3.arguments对象,存放的是调用某个方法所参过去的所有值,是一个伪数组-----(箭头函数中没有arguments)
function showargs() {
console.log(arguments);
}
let name = 'shiki'
showargs(1,2,3,4,5,name);
4.剩余参数(…obj)
// 使用三个...后加一个参数名,剩余参数就是将除去前面获取的参数后,剩余的参数都存放到一个数组里,剩余参数必须是在最后面
function showargs(...obj) {
console.log(obj);
}
let name = 'shiki'
showargs(1,2,3,4,5,name);
5.扩展运算符(…obj)
// 将一个数组分割成独立的参数传给函数
let name = [1,2,3,4,5,10]
console.log(Math.max(...name))
// 等同于
console.log(Math.max(1,2,3,4,5,10))
// 输出 10
6.箭头函数
let arr = (a,b) => a + b
arr()
// 箭头函数中this指向上一层
// 箭头函数没有arguments
// 箭头函数不是一个对象
7.解构赋值
// 结构赋值是对赋值运算符的一种扩展
// 它针对数组和对象进行操作
// 优点:代码书写简洁易读
let node = {
type:'icon',
birth:1999,
name:'shiki'
}
let {type, name} = node
//等同于
let type = node.type
let name = node.name
// 命名时必须时是当前对象或数组中存在的
// 可以使用默认值
// 可以使用剩余运算符,将剩下的对象存放到一个整体里面
let {type,birth = 1998,...res}= node
// 输出:icon 1999 {name: 'shiki'}
//对数组的结构赋值
//解构一定是数组一一对应
let arr1 = [1,2,3]
let [a,b] = arr1
console.log(a,b)
//输出: 1,2
// 可嵌套
let [a,[b],c] = [1,[2],3]
// 输出: 1,2,3
8.扩展的对象功能
// 直接写入变量和函数,作为对象的属性和方法
const name = "shiki"
const age = "23"
const person = {
name,
age,
// 等同于
// name : name,
// age : age,
sayName(){
console.log(this.name)
}
// 对象的方法
// is() 等价于 ===
// 比较两个值是否严格相等
let a = 1
let b = '1'
console.log(a==b,a===b)
console.log(Object.is(a,b))
// 输出: true false false
//assign() 对象的合并,主要用于浅拷贝
// Object.assign(target,obj1,obj2,...)
// 将obj1,obj2,...都合并存放到target里面
let newObj = Object.assign({},{name:'shiki'},{age:19})
console.log(newObj)
// 输出:{name: 'shiki', age: 19}
9.Symbol
// 原始数据类型 symbol ,表示独一无二的值
// 用途: 用来定义对象的私有变量
const name = Symbol('shiki')
const newname = Symbol('shiki')
console.log(name === newname)
// 输出:false
//定义对象的私有变量属性
let shiki = Symbol('shiki')
let obj = {
// 属性名引用外部变量的值时,要使用[变量名]
[shiki]:'两仪'
}
// 如果使用symbol定义的对象的变量,取值时一定要使用[变量名]
console.log(obj[shiki])
10.Set
// set 集合:表示无重复值的有序列表
let set = new Set()
// 添加元素
set.add(2)
set.add([1,2])
set.add({name:'shiki'})
set.add(2)
console.log(set)
//删除元素
set.delete(2)
//校验某个值是否存在与集合中,返回boolean值
set.has(2)
//访问集合的长度
console.log(set.size)
// 将set转换为数组,使用扩展运算符
let set2 = new Set([1,2,3,4,4,1])
let arr = [...set2]
console.log(set2,arr)
11.Map
// Map类型是键值对的有序列表,键和值是任意类型
let map = new Map()
map.set('name','shiki')
map.set('age',19)
map.has('name') // true
map.delete('age') //删除
map.clear()//清空
console.log(map)
console.log(map.get('name'))
12.数组的扩展功能
// 数组的方法
// 1.from() 将伪数组转换为真正的数组
function add(){
console.log(arguments)
let arr = Array.from(arguments)
//相较与from(),使用...扩展运算符可以更方便的转换为真数组
let arr1 = [...arguments]
//form()还可以接收第二个参数,用来对每个元素进行处理
let arr2 = Array.from(arguments,item => item + 1 )
console.log(arr)
console.log(arr1)
console.log(arr2)
}
//输出:
//Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]---伪数组
//(3) [1, 2, 3]---真数组
//(3) [1, 2, 3]---真数组
//(3) [2, 3, 4]---转为数组同时对每个元素进行+1操作
add(1,2,3)
//of() 将一组值(任意数据类型),转换为数组
console.log(Array.of(1,2,[3,4],{name:'shiki'},5))
//copywithin() 复制替换
let arr = [1,2,3,4,23,144].copyWithin(0,2)
console.log(arr)
// 将从2位置往后的所有数值复制,从0位置开始替换数组中的数据,会生成新数组
// (6) [3, 4, 23, 144, 23, 144]
// 2.find() 和 findIndex()
// find()只找出第一个符合条件的数组成员
let ab = [10,4,2,-7,4,-3].find( n =>{
// 条件语句
return n<0
})
console.log(ab)
// findIndex()只找出第一个符合条件的数组成员的下标
let ab1 = [10,4,2,-7,4,-3].findIndex( n =>{
// 条件语句
return n<0
})
console.log(ab1)
// 3.entries() keys() values() 返回一个遍历器,可以使用for...of循环进行遍历
console.log([1,2,3].keys())
// 输出:Array Iterator {}---数组遍历器
//keys()对键名或者下标进行遍历
for(let index of [1,2,3].keys()){
console.log(index)
}
//values()对值进行遍历
for(let item of [1,2,3].values()){
console.log(item)
}
//keys()对键值对进行遍历
for(let [idex,item] of [1,2,3].entries()){
console.log(idex,item)
}
//3.includes() 返回一个布尔值,表示某个数组是否包含给定的值
console.log([1,2,34,5].includes(4)) // false
//indexOf() 不存在返回-1,存在返回数值的下标
console.log([1,2,34,5].indexOf(4)) // -1
console.log([1,2,34,5].indexOf(5)) // 3
13.迭代器
// 迭代器 Iterator
//一种新的遍历机制(遍历器)
let arr = ['shiki','arlenx','hana']
console.log(arr) //(3) ['shiki', 'arlenx', 'hana']
let newarr = arr[Symbol.iterator]();
console.log(newarr) //Array Iterator {}
// 每次使用next()方法就遍历一次
console.log(newarr.next()) //{value: 'shiki', done: false}
// done为false时,继续遍历
console.log(newarr.next()) //{value: 'arlenx', done: false}
console.log(newarr.next()) //{value: 'hana', done: false}
// done为true时,遍历结束,就不会有数据undefined
console.log(newarr.next()) //{value: undefined, done: true}
14.生成器
// generator函数,可以通过yield关键字,将函数挂起,为了改变执行流提供了可能,同时为了做异步编程提供了方案
// 与普通函数的区别
// 1.function 后面,函数名之前有个 *
// 2.只能在函数内部使用yield表达式,让函数挂起
function* fn(){
yield 2;
yield 3;
}
// 返回一个遍历器对象
console.log(fn())
console.log(fn().next())
// console.log(fn().next())
15.promise对象
// Promise 对象
// 相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果
// 特点:
// 1.对象的状态不受外界影响,处理异步操作三个状态
// Pending(进行中) Resolved(成功结果) Rejected(失败结果)
// 2.状态一旦发生改变,就不会再变,任何时候都能得到这个结果
let code = 200
let pro = new Promise(function(resolve,reject){
// 执行异步操作
setTimeout(()=>{
if(code == 200){
resolve(code)
}else{
reject(code+100)
}
},1000)
})
pro.then(res =>{
console.log(res)
}).catch(err=>{
console.log(err)
})
// 封装一个promise
function timeOut(ms){
return new Promise((resolve,reject) =>{
setTimeout(()=>{
if(ms > 200){
resolve('不超时!')
}else{
reject('超时了!')
}
},1000)
})
}
timeOut(300).then(res =>{
console.log(res)
})
// resolve()方法
let p = Promise.resolve('shiki')
// 等价于
let p = new Promise(resolve => resolve('shiki'))
p.then(res =>{
console.log(res)
})
// reject()方法同上
//all() promise异步的并行操作
let p1 = new Promise((resolve,reject) =>{})
let p2 = new Promise((resolve,reject) =>{})
let p3 = new Promise((resolve,reject) =>{})
// 同时执行三个异步操作
let pAll = Promise.all([p1,p2,p3])
pAll.then(res =>{
// 只有三个异步操作都成功,才成功
}).catch(err=>{
// 有一个失败,则失败
})
// race() 请求超时
Promise.race([第一个方法加载某个东西,第二个方法设置超时时间])..then(res =>{
// 加载成功
}).catch(err=>{
// 请求超时
})
// finally() 放在所有promise执行之后,可以进行收尾工作
16.async 与 await
// 使得异步操作更加方便
// async返回是一个promise对象
async function fn(){
// 3.执行async中第一个同步任务
console.log('第二个执行')
// async中,先执行await中的代码
// await表示在这里等待一个promise返回结果后,再接下来执行
// 4.执行await方法,将返回值给msg,并将后面的任务放入promise.then异步任务队列中
let msg = await p
// 7.开始执行第二个微任务
console.log('第五个执行')
// 8.开始执行第三个微任务
console.log(msg)
return '第六个执行'
}
let p = new Promise(function(resolve,reject){
// 1.执行第一个同步任务,并将promise.then加入到异步队列中
console.log('第一个执行')
resolve('promise返回的结果');
}).then(res=>{
// 6.开始执行第一个微任务
console.log('第四个执行')
})
// 2.调用方法
fn().then(res=>{
// 9.执行完fn()方法,开始执行promise.then微任务
console.log(res)
})
// 同步操作
// 5.执行最后一个同步任务,开始执行微任务
console.log('第三个执行')
17.async,await,promise,setTimeout的执行顺序
setTimeout(function(){
// 10.执行第二个宏任务
console.log(1);
},1000);
setTimeout(function(){
// 9.执行第一个宏任务
console.log(2);
},0);
new Promise(function(resolve,reject){
// 1.执行第一个同步任务,并将promise.then放入到异步微任务队列中等待
console.log(3);
resolve();
}).then(()=>{
// 7.执行微任务队列中的第一个任务
console.log(4);
});
async function async1(){
// 3.执行同步任务
console.log(5);
// 4.执行await中的promise对象,并将之后的任务放入到promise.then微任务队列中等待
await async2();
// 8.执行第二个微任务,至此所有微任务结束,开始执行宏任务
console.log(6);
}
async function async2(){
// 5.执行async的同步任务
console.log(7);
}
// 2.调用方法
async1();
// 6.顺序查找并执行同步任务,至此所有同步任务都执行完成,开始找微任务
console.log(8);
async function async1() {
// 4.顺序执行第一句,同步任务
console.log('async1 start');
// 5.执行await中的方法,将返回的promise对象加入到异步队列中,async中剩下的语句全部变成promise.then的微任务,并加入到队列中
await async2();
// 9.同步任务执行完,开始执行异步队列中的第一个微任务
console.log('asnyc1 end');
}
async function async2() {
// 6.顺序执行第一句,同步任务
console.log('async2');
}
// 1.第一个同步任务
console.log('script start');
// 2.将宏任务放入异步队列中等待
setTimeout(() => {
//10.微任务执行完开始执行宏任务
console.log('setTimeOut');
}, 0);
// 3.调用方法
async1();
new Promise(function (reslove) {
// 7.顺序执行promise中的同步任务
console.log('promise1');
reslove();
}).then(function () {
// 10.顺序执行第二个异步微任务
console.log('promise2');
})
// 8.继续执行同步任务
console.log('script end');
18.class类 和 构造函数
// es5 构造函数
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.sayName = () => this.name
let p1 = new Person('shiki',19)
console.log(p1)
// es6 class
class Person1{
constructor(name,age){
this.name = name
this.age = age
}
sayName(){
return this.name
}
}
let p1 = new Person1('shiki',19)
console.log(p1)
// 类的继承 extends
class Student extends Person1{
constructor(name,age,studentid){
// 继承父类的属性
super(name,age)
this.studentid = studentid
}
//子类自己的方法
sayStudentid(){
return studentid
}
//重写父类的方法
sayName(){
return "学生姓名:"+this.name
}
}
let stu1 = new Student ('shiki',19,15142002)
console.log(stu1)
19.es6模块化
// es6 module
// 两个命令export 和 import
// 抛出模块的两种方式 01
export const name ='张三'
export functiion fn(){
console.log('你好')
}
// 抛出模块的两种方式 02
const obj = {
name:'shiki'
}
export default obj
// 导入模块的方式
// JS用法
<script type='module'>
import { name,fn,obj } from './路径'
</script>
// Vue用法
<script>
import { name,fn,obj } from './路径'
</script>
// 导入所有模块
import * from './路径'
// 导入所有模块重命名
import * as allmodule from './路径'
// allmodule 就是一个包含所有模块的对象
// allmodule.fn() 调用里面的fn方法