1. Promise
promise中的all方法
promise中的all方法 不是我们所说的使用promise对象定义的方法 它是使用Promise构造方法定义的方法
它是一个可以执行多个Promise的一种方式 all方法 执行全部的promise
Promise.all() 方法 内置一个参数 参数是一个数组 数组中的每一个元素 都是Promise
他们都会一起执行
let p1 = new Promise((resolve,reject)=>{
console.log(1111);
resolve('这是第一个Promise');
})
let p2 = new Promise((resolve,reject)=>{
console.log(2222);
resolve('这是第二个Promise');
})
let p3 = new Promise((resolve,reject)=>{
console.log(3333);
resolve('这是第三个Promise');
})
let p = Promise.all([p1,p2,p3]);
p.then(data=>console.log(data));
promise中的race方法
race方法和all方法是一样的 都不是对象方法 都是Promise直接调用的方法 内置也是一个参数 参数还是数组
但是不同的是 race方法不是将所有的promise都执行 而是只执行最快的那个Promise
<script>
let p1 = new Promise((resolve,reject)=>{
setTimeout(() => {
// console.log('这是三秒的promise');
resolve('这是三秒的promise');
}, 3000);
})
let p2 = new Promise((resolve,reject)=>{
setTimeout(() => {
// console.log('这是一秒的promise');
resolve('这是一秒的promise');
}, 1000);
})
let p3 = new Promise((resolve,reject)=>{
setTimeout(() => {
// console.log('这是两秒的promise');
resolve('这是两秒的promise');
}, 2000);
})
// race只是执行最快那个promise
let p = Promise.race([p1,p2,p3]);
p.then(d=>console.log(d));
</script>
promise配合ajax
小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>ajax和promise</h1>
</body>
</html>
<script src="./jquery.js"></script>
<script>
let promise = new Promise((resolve,reject)=>{
setTimeout(() => {
$.ajax({
url : './index.php',
type : 'get',
data : {
user : 'Eric'},
success : (response)=>{
resolve(response);
},
error : (err)=>{
reject(err);
}
})
}, 200);
})
promise.then(data=>{
console.log(data);
})
let promise1 = new Promise((resolve,reject)=>{
$.ajax({
url : './indexx.php',
type : 'get',
success : (response)=>{
resolve(response);
},
error : (err)=>{
reject(err);
}
})
})
promise1.then(data=>{
console.log(data);
})
</script>
处理异步问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>ajax和promise</h1>
</body>
</html>
<script src="./jquery.js"></script>
<script>
let promise = new Promise((resolve,reject)=>{
setTimeout(() => {
$.ajax({
url : './index.php',
type : 'get',
data : {
user : 'Eric'},
success : (response)=>{
resolve(response);
},
error : (err)=>{
reject(err);
}
})
}, 200);
})
promise.then(data=>{
console.log(data);
return $.ajax({
url : './indexx.php',
type : 'get',
success : (response)=>{
return data + response
},
error : (err)=>{
reject(err);
}
})
}).then(data=>{
console.log(data);
})
</script>
2. async…await
async…await是promise和generator的语法糖 他是真正意义上解决异步问题的一种方式
promise解决异步问题 但是不能从我们promise中取出数据 而async…await是可以做到的
他和generator是一样的 控制函数的执行过程 但是generator是手动的 async是自动的
因为generator需要手动的调用next执行 但是async不需要在外部手动调用
async是修饰函数 这个函数的返回值就是一个promise对象
async函数中可以有await 他的作用和yield比较相似 程序碰到await会陷入阻塞状态 阻塞到将await后面的表达式执行完毕
执行完毕之后再向下执行 await只存在在async修饰的函数中
async函数中的await可以直接获取promise中的resolve或者是reject状态 并且是异常处理之后的状态
也就是说 他可以直接获取出promise的数据
async的主要作用
1.async的返回值是一个promise状态
2.async中的await获取promise中的状态 并且是异常处理之后的状态
3.可以将异步的代码转变成同步的代码 将异步的程序以同步的流程表达出来
// 使用async函数 他的返回值是promise
// async function fun(){
// }
// // 只要是使用async修饰的函数的返回值 那么返回值就是promise
// console.log(fun());
// async中的await可以直接获取promise的状态
function to(){
return new Promise((resolve,reject)=>{
resolve('这是函数的resolve装填');
})
}
// let a = to().then(data=>console.log(data))
// console.log(a);
async function test(){
let a = await to();
console.log(a);
}
test();
小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>async...await</h1>
</body>
</html>
<script src="./jquery.js"></script>
<script>
function p1(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
$.ajax({
url : './index.php',
type : 'get',
data : {
user : 'Eric'},
success : (response)=>{
resolve(response);
},
error : (err)=>{
reject(err);
}
})
}, 200);
})
}
function p2(){
return new Promise((resolve,reject)=>{
$.ajax({
url : './indexx.php',
type : 'get',
success : (response)=>{
resolve(response);
},
error : (err)=>{
reject(err);
}
})
})
}
// p1().then(d=>console.log(d));
// p2().then(d=>console.log(d));
async function test(){
let v1 = await p1();
console.log(v1);
let v2 = await p2();
console.log(v2);
}
test()
</script>
3. 面向对象
面向对象和面向过程的区别
面向对象指的是将一些可能用到的东西 或者说使用起来比较繁琐的内容 将其封装 使用的时候直接调用
面向过程 在使用的时候定义 如果需要再次使用 那么再次定义
面向对象其实实现的就是封装
面向对象的概念
面向对象的三大特性 封装 继承 多态
多态 : 同一操作 针对不同的对象 会产生不同的执行结果 这就是多态
面向对象的优势:
使用方便 方便项目维护
避免代码冗余
类和对象的关系
类 : 类是泛指的一类事务 抽象
对象 : 对象指的是指定的某件事务 具体
类是对象的抽象 对象是类的具体
类是对象的模板 对象是类的铸件
类的成员
我们在使用对象的时候 这个对象一定是在类中产出的
所以说 我们在使用对象之前 一定先定义一个类
使用class关键字 后面直接跟上类名 类名的命名方式使用帕斯卡命名法
类中存在的成员:
成员属性 : 和变量类似 但是有区别 成员属性在类中是全局的 变量不是 参数也不是
属性指的是对一个事务的描述 一般是名词或者是形容词
成员方法 : 和函数类似 但是有区别 成员方法在类中是全局的
方法指的是一种行为 一般是动词
定义和实例化一个类
定义使用class定义 实例化的时候 使用new进行实例化
new后面加上 类名 实参列表
<script>
// 定义一个类
class Person{
// 定义类中的成员
name = 'Eric';
age = 18;
// 定义类中的方法
say(pass){
var user = 'amdin';
this.pass = pass;
console.log(this.name + '在说话');
}
eat(){
// console.log(user);
console.log(this.pass);
this.say();
console.log(this.name + '在吃饭');
}
}
let p = new Person();
console.log(p.name);
console.log(p.age);
p.say('123')
p.eat()
</script>
构造器
构造器 其实是面向对象中的一个特殊的方法 为什么特殊 因为他不需要你手动调用 只要是进行了实例化 那么就会自动调用
构造器在你实例化的时候会被自动调用的
// 构造器
class Dog{
constructor(){
console.log('构造器在实例化的时候已经被调用了');
}
}
new Dog();
构造器的作用
主要用来初始化数据 可以接受参数
那么什么时候向构造器中传参 因为constructor不需要我们手动调用 只需要自动调用
那么 我们使用这个构造器的时候 什么时候传参
实例化的时候有实参 但是类名没有形参
构造器有形参 但是不需要调用 没有实参
他们两个一起执行 都是在实例化的同时执行 所以说 我们可以在实例化的时候传递参数
<script>
// 构造器
// class Dog{
// constructor(){
// console.log('构造器在实例化的时候已经被调用了');
// }
// }
// new Dog();
// class Dog{
// constructor(name,color,age){
// console.log(name,color,age);
// }
// }
// new Dog('大黄','黑色的',3);
class Dog{
constructor(name,color,age){
this.name = name;
this.age = age;
this.color = color;
}
sound(){
console.log(this.food);
console.log(`${
this.name}每天晚上喵喵叫`);
}
eat(food){
this.food = food;
console.log(`${
this.name}今年${
this.age}岁,每天吃的很多${
this.food}`);
}
}
let wd = new Dog('小黑','白色的',3);
wd.eat('狗粮');
wd.sound();
</script>
类的继承
一个类中有另一个类的属性和方法 这就是继承
<script>
// 定义一个基类 也叫父类
class Worker{
constructor(name,money){
this.name = name;
this.money = money;
}
// 定义周报方法
zb(){
console.log(this.name + '的周报');
}
// 定义绩效的方法
jx(){
console.log(this.name + '的绩效是奖金加上' + this.money);
}
}
// 派生类 子类
class Boss extends Worker{
szb(){
console.log(this.name + '在审核下属的周报');
}
sjx(){
console.log(this.name + '在审核下属的绩效');
}
}
let w = new Worker('Eric',35);
w.zb();
w.jx();
let b = new Boss('Mary',10);
b.zb();
b.jx();
b.szb();
b.sjx();
</script>
方法的重写
方法的重写 也叫方法的覆写 所以说 一般情况下我们在子类中重写方法的时候
都是使用方法名把父类的方法覆盖掉 直接重新定义
<script>
// 定义一个基类 也叫父类
class Worker{
constructor(name,money){
this.name = name;
this.money = money;
}
// 定义周报方法
zb(){
console.log(this.name + '的周报');
}
// 定义绩效的方法
jx(){
console.log(this.name + '的绩效是奖金加上' + this.money);
}
}
// 派生类 子类
class Boss extends Worker{
szb(){
console.log(this.name + '在审核下属的周报');
}
sjx(){
console.log(this.name + '在审核下属的绩效');
}
jx(){
console.log(this.name + '说:我的绩效和你们的绩效不一样 我是按照季度算的');
console.log('我的绩效是零花钱');
}
}
let w = new Worker('Eric',35);
w.zb();
w.jx();
let b = new Boss('Mary',10);
b.zb();
b.jx();
b.szb();
b.sjx();
</script>
继承构造器
但是 我们注意一下 有一个方法不能覆写 那就是构造器方法
这个方法可以继承 如果说父类中的构造器无法满足子类中的需求了 那么我们可以在子类中重新定义构造器
但是在重新定义构造器的时候 必须将父类的构造器方法继承过来
继承构造器 使用关键字super
使用super继承父类的构造器 并且 我们需要继承父类构造器中的所有的参数
<script>
class Worker{
constructor(name,money){
this.name = name;
this.money = money;
}
zb(){
console.log(this.name + '的周报');
}
}
// 继承构造器
class Boss extends Worker{
// 方法的覆写 失败
// constructor(name,money,age) {
// console.log(name,money,age);
// }
// 方法的重写 不带已继承参数
// constructor(age) {
// this.age = age;
// }
constructor(name,money,age) {
super(name,money);
this.age = age;
}
szb(){
console.log(this.name + '在审核下属的周报');
}
sjx(){
console.log(this.name + '在审核下属的绩效');
console.log(this.name + "年龄是" + this.age + "收取是" + this.money);
}
}
let w = new Worker('Eric',35);
w.zb();
let b = new Boss('Mary',10,35);
b.sjx();
</script>
静态方法
静态方法是存储在数据段的内存 他对每一个段都是开放的
所以说 使用静态方法不需要实例化 就可以直接使用
静态方法的运行效率要比常规的对象方法快55%
定义静态方法的时候 我们需要 static 修饰的方法
使用静态方法的时候 使用 类名.方法名()
静态方法注意事项
在静态方法中 不能使用非静态成员 如果想使用成员 那么必须将成员设定为静态成员
不能使用构造器初始化静态成员
<script>
class Car{
constructor (name,color){
// this.name = name;
// this.name = 'Eric'
this.color = color;
}
static name = 'Eric'
// 定义静态方法
static start() {
// console.log(this.name + '汽车已经启动');
console.log(Car.name + '汽车已经启动');
}
stop(){
Car.start();
console.log('停车');
}
}
// 使用静态方法 不需要实例化
Car.start();
let c = new Car('benz','黑色');
c.stop();
</script>
4. ES6模块