关于这个视频的笔记
(https://www.bilibili.com/video/BV1uK411H7on?p=29&vd_source=3cf72bb393b8cc11b96c6d4bfbcbd890)
1.ES6
1.1let的一些注意点
let a;
let b,c,d;
let e = 100;
let f="你好",g=101;
// 变量名不能重复声明
// let testDepulicate = 123456
// let testDepulicate = 789;
// var是可以重复声明的
// var testDepulicate = 123456
// var testDepulicate = 789;
// let 是块级作用域 var是全局作用域
/*
{
let test01 = 123
}
console.log(test01); //报错test01 is not defined
*/
/*
{
var test01 = 123
}
console.log(test01); //正常运行
*/
// 不允许变量提升, 简单来说,声明之前不能使用, var是可以的
console.log(test02);
let test02 = 'adfa' //Cannot access 'test02' before initialization
1.2const 常量的一些注意点
1.3 变量的解构赋值
数组的解构赋值
个人理解:对数组里面的值单独定义一个变量名
对象的解构赋值
个人理解:对象里面的值单独定义一个变量名
1.4 模板字符串
// 用反引号 定义
let str = `我是模板字符串`
console.log(str);
//可以出现换行符
let str2 = `我是模板
123字符串`
console.log(str2);
// 变量拼接
let test01 = '123haod'
let test02 = `${test01}拼接了`
console.log(test02);
1.5对象的简化写法
let name1 = '米粒'
let show = function(){
console.log("show time");
}
let user = {
name1,
show,
//简化方法声明
learn(){
console.log("学习");
}
}
console.log(user);
console.log(user.show());
console.log(user.learn());
1.6箭头函数
<script>
let testf1 = function(name){
console.log(`my name is ${name}`);
}
let testf2 = (name)=>{
console.log(`my name2 is ${name}`);
}
testf1('a')
testf2('好人')
// 1.this 是静态的,this始终指向函数声明的所在作用域下的this的值
let testf3 = function(){
console.log(this.name);
}
let testf4 = ()=>{
console.log(this.name);
}
window.name='全局的name'
const school={name:'学校名字'}
//直接调用
testf3()
testf4()
//call 调用
testf3.call(school) //学校的名字 js原本的this,谁调用,this就指向谁
testf4.call(school) //this 函数声明时候 所在的作用域
// 2. 不能作为构造实例化对象
let Person = (name,age)=>{
this.name = name,
this.age = age
}
// let me = new Person('Ray',18)
// console.log(me); //报错Person is not a constructor
//3. 不能使用arguments变量
let testf5 = function(){
console.log(arguments);
}
let testf6 = ()=>{
console.log(arguments);
}
testf5('1',2,3)
// testf6('1',2,3) //报错,箭头函数不能使用arguments
//4.箭头函数的简写,只有一个参数括号可以简写,
//当代码体只有一句话时候,可以省略花括号{},而且return也要省略,默认作为return的返回值
let testf7 = n=> console.log(n);
testf7(11)
</script>
箭头函数的应用场景
setTimeout() 函数的this指向的是window,但是使用箭头函数可以让this指向箭头函数声明的时候的作用域
setTimeout(()=>{
this.xxxx
})
1.6.1箭头函数 箭头函数的注意点
箭头函数适合与this无关的回调,定时器,数组的方法回调
箭头函数不适合this有关的回调, 比如事件回调,对象的方法
1.7函数默认值
function f (a,b,c=10){
console.log(a+b+c);
}
f(1,2,3)
f(1,2)
//与解构赋值结合
function connect({host='127.0.0.1',name,port}){
console.log(host);
console.log(name);
console.log(port);
}
connect({
// host:"1.2.3.4",
name:"rott",
port:"3306"
})
1.8 rest参数
// es5的用法
function test01(){
console.log(arguments); //arguments是一个对象
console.log(typeof arguments);
}
test01('参数1','参数2','参数3')
//用es6 rest参数方式,需要放到最后一个参数
// function test02(a,...args,b){} //args需要放到最后一个参数
function test02(...args){
console.log(args); //是一个数组
console.log(typeof args); //数组也是返回object,而复杂数据类型里,除了函数返回了"function"其他均返回“object”
console.log(args.constructor===Array); //判断是否是数组
}
test02('参数1','参数2','参数3')
1.9拓展运算符
拓展运算符,能将数组转为逗号分隔的参数序列
const tfBoys=['boy01','boy02','boy03']
console.log(tfBoys);
console.log(...tfBoys);
function showBoys(){
console.log(arguments);
}
showBoys(tfBoys) //[Arguments] { '0': [ 'boy01', 'boy02', 'boy03' ] }
showBoys(...tfBoys)//[Arguments] { '0': 'boy01', '1': 'boy02', '2': 'boy03' }
1.9.1拓展运算符的运用
<body>
<div></div>
<div></div>
<div></div>
</body>
<script>
// 1. 数组的合并
const array01=['a1','a2','a3']
const array02=['a4','a5','a6']
// es5的做法
const array04=array01.concat(array02)
console.log(array04);
//es6的做法
const array03=[...array01,...array02]
console.log(array03);
//2.数组的克隆
const array05= ['a','b','c']
const array06= [...array05] //如果有引用,那么是浅拷贝
console.log(array06);
//3.将伪数组转为真的数组
const object01=document.querySelectorAll('div')
console.log(object01);
const array07 = [...object01]
console.log(array07);
</script>
1.10Symbo的基本使用
let s = Symbol();
console.log(s,typeof s);
// 参数只是一个标志,值是不一样的,所以是false
let s2 = Symbol('张三');
let s3 = Symbol('张三');
console.log(s2===s3);//false
//用for创建,那么相当于描述字符串指定一个值,那么对比值就是true
let s4 = Symbol.for('李四')
let s5 = Symbol.for('李四')
console.log(s4===s5);//true
//symbol不能进行数据运算,比较,计算
//js数据类型
//USONB you are so niubility 记忆
//U undefined
//S String,Symbol
//O object
//N number,null
//B boolean
1.10.1Symbol创建对象属性
<script>
// 1.防止对象里的属性重名
let game={
up:function(){
console.log('game up');
},
down:function(){
console.log('game down');
}
}
let methods={
up:Symbol(),
down:Symbol()
}
game[methods.up]=function(){
console.log("methods - up");
}
game[methods.down]=function(){
console.log("methods - down");
}
//这样就实现了对象里面添加其他方法,又不会重名
console.log(game);
console.log(game.up);
console.log('---------------');
let game2={
//第二种定义方法
[Symbol('up')]:function(){
console.log("up---------");
}
}
console.log(game2);
</script>
1.10.2Symbol常用的内置属性
1.10.2.1 Symbol.hsInstance
1.10.2.1 Symbol.isConcatSpreadable
1.11迭代器
1.11自定义对象迭代器
let myClass={
name:"super man class",
stu:[
'超人',
'钢铁侠',
'绿巨人'
],
[Symbol.iterator](){
let index=0;
let _this = this;
return {
next: function(){
if(index<_this.stu.length){
return {value:_this.stu[index++],done:false}
}else{
return {value:undefined,done:true}
}
}
}
}
}
// for (let item of myClass.stu) {
// console.log(item);
// }
//[Symbol.iterator]()自定义这个之后,就可以了遍历自定义的遍历
for (let item of myClass) {
console.log(item);
}
1.12生成器
生成器是一个特殊的函数
异步编程新的解决方案
1.12.1生成器初步使用
function * gen(){
console.log("hello generator");
}
function * gen2(){
console.log("hello generator2");
}
// 加入yeild "暂停点"
function * gen3(){
console.log("111");
yield "第一个暂停点"
console.log("222");
yield "第一个暂停点"
console.log("333");
yield "第一个暂停点"
console.log("444");
}
let r1 = gen();
r1.next(); //用next才能执行
let r2 = gen2();
r2.next();//用next才能执行
// let r3 = gen3();
// r3.next();//用next才能执行
// r3.next();//用next才能执行
// r3.next();//用next才能执行
// r3.next();//用next才能执行
// r3.next();// 空的没执行,因为已经全部执行完了
let r3 = gen3();
console.log(r3.next());//输出yield
console.log(r3.next());//输出yield
console.log(r3.next());//输出yield
console.log(r3.next());//输出yield
console.log(r3.next());//输出yield
//遍历
// for (const v of gen3()) {
// console.log(v); //输出yield内容
// }
for (const v of r3) {
console.log(v);
}
1.12.2生成器参数使用
function * gen(args){
console.log(args);
let one = yield 111;
console.log(one)
let two = yield 222;
console.log(two);
yield 333;
}
let iterator = gen('AAA');
console.log(iterator.next()) //第一次参数,调用next() args
console.log(iterator.next('BBB'))//第二次调用next,会作为第一个业务代码整体返回的结果
console.log(iterator.next('CCC'))//第三次调用next,会作为第二个业务代码整体的返回结果
console.log(iterator.next())
console.log(iterator.next())
1.12.3生成器和异步编程
//需求,一秒后输出111,然后两秒后输出222,三秒后输出333
//传统的异步编程,当足够多时候,会出现"回调地狱"现象
// setTimeout(() => {
// console.log(111);
// setTimeout(() => {
// console.log(222);
// setTimeout(() => {
// console.log(333);
// }, 3000);
// }, 2000);
// }, 1000);
//用iterator
function f1(){
setTimeout(() => {
console.log(111);
iterator.next()
}, 1000);
}
function f2(){
setTimeout(() => {
console.log(222);
iterator.next()
}, 2000);
}
function f3(){
setTimeout(() => {
console.log(333);
}, 3000);
}
function * f(){
yield f1()
yield f2()
yield f3()
}
let iterator = f();
iterator.next()
//需求,查询用户,根据用户查询订单,查询商品
//这个案例是有参数作为返回值
//用iterator
function getUser(){
setTimeout(() => {
let user = '张三'
iterator.next(user)
}, 1000);
}
function getOrder(){
setTimeout(() => {
let order = '订单10'
iterator.next(order)
}, 1000);
}
function getGoods(){
setTimeout(() => {
let good = '商品:芭比娃娃'
iterator.next(good)
}, 1000);
}
function * f(){
let user = yield getUser()
console.log(user);
let order = yield getOrder()
console.log(order);
let goods = yield getGoods()
console.log(goods);
}
let iterator = f();
iterator.next()
1.13 Promise
let p = new Promise(function(resolve,reject){
setTimeout(() => {
// let data = '成功的数据'
// resolve(data) //调用then第一个参数的方法
let data = '失败的数据'
reject(data) //调用then第二个参数的方法
}, 1000);
})
p.then((res)=>{
console.log(res);
},(err)=>{
console.error(err);
})
读取文件的一个promise实践
// 读取文件
let fs = require('fs');
//1. 用fs传统方法
// fs.readFile('./测试文件.txt',(err,data)=>{
// if(err) throw err
// console.log(data.toString());
// })
//2.用promise改进
let p = new Promise((resolve,reject)=>{
fs.readFile('./测试文件.txt',(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
p.then(res=>{
console.log(res.toString());
},err=>{
console.log(err);
})
1.13.1Promise封装AJAX请求
<script>
/*
//1.创建对象
const xhr = new XMLHttpRequest();
const url = 'https://api.apiopen.top/api/sentences'
// const url = 'https://api.apiopen.top/api/sentences22'//错误
//2.初始化
xhr.open('get',url)
//3.发送
xhr.send()
//4.绑定事件
xhr.onreadystatechange = function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<=299){
console.log(xhr.response);
}else{
console.error(xhr.status);
}
}
}
*/
// ----------------------------------
// 用promise改造
const p = new Promise((resolve,reject)=>{
//1.创建对象
const xhr = new XMLHttpRequest();
const url = 'https://api.apiopen.top/api/sentences'
// const url = 'https://api.apiopen.top/api/sentences22'//错误
//2.初始化
xhr.open('get',url)
//3.发送
xhr.send()
//4.绑定事件
xhr.onreadystatechange = function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<=299){
resolve(xhr.response)
}else{
reject(xhr.status);
}
}
}
})
p.then(res=>{
console.log(res);
},err=>{
console.log(err);
})
</script>
1.13.3Promise.prototype.then方法
<script>
const p = new Promise((resolve,reject)=>{
resolve('成功了')
// reject('失败了')
})
/*
这里then的返回值有三种
1.非promise return '123'; //这个就是非promise
2.promise类型,而且返回值就是返回的promise里面的值
*/
let result = p.then(res=>{
console.log(res);
// return '123'; //这个就是非promise
//默认没有return 是默认promise
//下面就是返回promise类型
return new Promise((resolve,reject)=>{
resolve('ok')//这个是成功的promose
// reject('error')//这个是失败的promise
// throw 'error'
})
},err=>{
console.error(err);
})
console.log(result);
// ----------------
// 链式调用
// p.then(res=>{
// console.log(res);
// },err=>{
// console.error(err);
// }).then(res=>{
// console.log(res);
// },err=>{
// console.error(err);
// }).then(res=>{
// console.log(res);
// },err=>{
// console.error(err);
// })
</script>
1.13.4Promise对象catch方法
catch来处理错误的回调
<script>
const p = new Promise((resolve,reject)=>{
// resolve('成功了')
reject('失败了')
})
// p.then(res=>{
// },err=>{
// console.error(err);
// })
p.catch(err=>{
console.warn(err);
})
</script>