8、ES6中的类
8.1 声明
本质上ES5和ES6中类的使用是一样的。ES6中的class可以理解为构造函数的语法糖
{ // ES5中声明类的常用方式 function Person(name,age){ this.name = name; this.age = age; } Person.prototype.sayHello = function(){ console.log(`你好,我是${this.name}`) } let p1 = new Person('张三',18); p1.sayHello(); console.log(p1); } { // ES6中声明类 本质上整个Person就是构造函数 class Person{ constructor(name,age){ this.name = name; this.age = age; } sayHello(){ console.log(`你好,我是${this.name}`) } } let p1 = new Person('张三',18); p1.sayHello(); console.log(p1) }
8.2 继承
{ // ES5中声明类的常用方式 function Person(name,age){ this.name = name; this.age = age; } Person.prototype.sayHello = function(){ console.log(`你好,我是${this.name}`) } let p1 = new Person('张三',18); p1.sayHello(); console.log(p1); } { // ES6中声明类 本质上整个Person就是构造函数 class Person{ constructor(name,age){ this.name = name; this.age = age; } sayHello(){ console.log(`你好,我是${this.name}`) } } let p1 = new Person('张三',18); p1.sayHello(); console.log(p1) } { // es5继承 function Person(name){ this.name = name; } Person.prototype.sayHello = function(){ console.log("person",this.name) } function Man(name,age){ this.age = age; Person.call(this,name); } Man.prototype = new Person(); Man.prototype.showAge = function(){ console.log("man",this.age,this.name) } var man = new Man("张三",17); man.showAge(); console.log(man); } { // ES6中的实现 class Person{ constructor(name){ this.name = name; } sayHello(){ console.log("person",this.name) } } class Man extends Person{ constructor(name,age){ // 必须调用super 才能使用this super(name); this.name = name; this.age =age } showAge(){ console.log("man",this.age,this.name) } } var man = new Man("张三",17); man.showAge(); console.log(man); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Js Class extends</title> <style> * { margin-top: 20px; } h5 { color: red; } span { color: blue; } </style> </head> <body> <h5>Js 类继承 extends</h5> <div>继承类声明 使用关键字 extends</div> <div>如果子类中存在构造函数 constructor(),则需要在使用“this”之前调用 super() 代替父类构造函数</div> <div> <span>js 输出: </span> <span id="idconsole"></span> <!-- 显示时间 --> <div></div> </div> </body> <script> // 父类 class Animal { constructor(name) { this.name = name;// 类属性声明不须要var声明 , var parrent = '';是声明普通变量 } // 成员方法 speak() { console.log(this.name + ' makes a noise.'); //仿问类属性要使用 this. } } // 子类 继承自 Animal class Dog extends Animal { master = ''; // Dog 比父类Animal 多了新属性master constructor(name, master) { super(name); // 调用 super() 代替父类构造函数,初始化与父类共同的属性name this.master = master; // 初始化子类新属性master } // 重载父类成员方法 speak speak() { let logstr = this.name + ' is a Dog, ' + 'has master from ' + this.master + ' .'; let logelement = document.getElementById('idconsole'); logelement.innerHTML = logstr; logelement.nextElementSibling.innerHTML = 'time: ' + new Date().toLocaleString(); } } var d = new Dog('Wangwang', 'People'); // 构造新实例 Dog d.speak(); // 调用Dog成员方法 </script> </html>
9、export和import
module1.js
// export 分别导出 变量、方法和类。 // 声明和导出在一起 export let a = 18; export function func(){ console.log('hello') } export class Person{ sayHello(){ console.log('person'); } }
module2.js
// 先声明 let a = 12; function func(){ console.log('hello') } class Person{ sayHello(){ console.log('person'); } } // 后导出(推荐) export default{ a, func, Person }
导入
<script type="module"> // 第一种导入 按需导入的名称要和exprot 中对应 import {a,func, Person} from './js/module1.js'; console.log(a); console.log(func); console.log(Person); // 第二种导入 一次性导入所有的export。 import * as module1 from './js/module1.js'; console.log(module1.a); console.log(module1.func); console.log(module1.Person); //第三中导入 (推荐)配合export default import module2 from './js/module2.js'; console.log(module2.a); console.log(module2.func); console.log(module2.Person); </script>
10、异步编程
1. 什么是同步
当⼀一个"调用"发出时,在没有得到结果之前,这个"调用"就会阻塞后面代码的执行, 得到结果的时候才会返回。换句话说,"调⽤者"要主动等待代码的执行结果,得到返回结果 后,程序才会继续运行
2.什么是异步
"调用"发出的时候,就直接返回了,对应的结果会通过状态、通知来告诉"调用者"或通 过回调函数处理这个调用。异步调用发出后,不会阻塞后面的代码。
3.JavaScript中为什么要引入异步这个概念
JavaScript是单线程的
同步代码会阻塞后面的代码
异步不会阻塞程序的运⾏
4.JavaScript中异步的实现
回调函数
// ⼀层的回调函数 $.get('http://api.xxx.com/xxx', callback) /** * 请求后台类型列列表,根据类型名称获取要请求的列列表id,再根据id获取列表详细内容 * 难以维护,这就是回调地狱了 **/ $.ajax({ url: "type", data:1, success: function (a) { $.ajax({ url: "list", data:a, success: function (b) { $.ajax({ url: "content", data:b, success: function (c) { console.log(c) } }) } }) } })
setInterval和setTimeout
Promise
Generator
async
10.1 promise
{ function func1(resolve,reject){ var timeOut = Math.random() * 2; setTimeout(()=>{ console.log('任务1',timeOut); if(timeOut<1){ resolve("执行结果"); // 调用promise的then中的方法 }else{ reject("执行报错"); // // 调用promise的catch中的方法 } },1000); } let p1 = new Promise(func1); let p2 = p1.then(function(response){ console.log("执行完了"+response) }); let p3 = p2.catch(function(error){ console.log("执行出错了"+error); }) } { // ajax1 ajax2 ajax3 都是Promise对象 function ajax1(num){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log("任务1",num+1); resolve(num+1); },1000) }); } function ajax2(num){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log("任务2",num+2); resolve(num+2); },1000) }); } function ajax3(num){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log("任务3",num+3); resolve(num+3); },1000) }); } ajax1(1).then(ajax2).then(ajax3); }
Promise.all()方法
{ // 定义Promise方法,传入要相加的数字 function getNum(num){ return new Promise((resolve,reject)=>{ resolve(num); }); } function sum(nums){ let result = 0; nums.forEach(num=>{ result = result + num; }); console.log(result); } // 使用Promise.all 方法,此方法传入多个Promise方法,保证这些方法都全部完成,才执行then // Promise.all()返回的也是一个Promise实例。then方法传入的参数是前面多个方法中resolve的参数数组 Promise.all([getNum(1),getNum(2),getNum(9)]).then(sum); }
Promise.race() 方法
{ // 定义Promise方法,传入要相加的数字 function getNum(num){ return new Promise((resolve,reject)=>{ resolve(num); }); } function showNum(num){ console.log(num); } // Promise.race方法 用于希望多个方法,率先返回的结果就是整个Promise的结果 Promise.race([getNum(11),getNum(2),getNum(9)]).then(showNum); }