From aa1c081f0e192fe45c06940adf59ca79d6a4ffd4 Mon Sep 17 00:00:00 2001 From: giteeyunyunyun <18883994582@163.com> Date: Sun, 16 May 2021 14:46:20 +0800 Subject: [PATCH] 19-week -homework --- ...47\345\210\266\346\265\201-19-1noteyun.md" | 275 +++++++++++++++++ ...17\347\273\247\346\211\277-19-2noteyun.md" | 218 ++++++++++++++ ...omise\343\200\201asyncwait-19-3noteyun.md" | 277 ++++++++++++++++++ 3 files changed, 770 insertions(+) create mode 100644 "\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/JS\351\200\273\350\276\221\346\216\247\345\210\266\346\265\201-19-1noteyun.md" create mode 100644 "\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\257\271\350\261\241\345\222\214\347\261\273\343\200\201\346\236\204\351\200\240\345\207\275\346\225\260\345\222\214this\345\216\237\345\236\213\351\223\276\345\274\217\347\273\247\346\211\277-19-2noteyun.md" create mode 100644 "\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\274\202\346\255\245JS\343\200\201callbacks\357\274\210\345\274\202\346\255\245\345\233\236\350\260\203\357\274\211\343\200\201promise\343\200\201asyncwait-19-3noteyun.md" diff --git "a/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/JS\351\200\273\350\276\221\346\216\247\345\210\266\346\265\201-19-1noteyun.md" "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/JS\351\200\273\350\276\221\346\216\247\345\210\266\346\265\201-19-1noteyun.md" new file mode 100644 index 00000000..d0a72fac --- /dev/null +++ "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/JS\351\200\273\350\276\221\346\216\247\345\210\266\346\265\201-19-1noteyun.md" @@ -0,0 +1,275 @@ +19-1noteyun + +# 循环语句 + +- `for循环` + + ```javascript + // 类似python中的for i in range(20) + for(let i=0; i<20; i++){ + console.log(i) + } + + 1 + 2 + …………………… + 17 + 18 + 19 + + Process + ``` + +- `while循环` + + ```javascript + const MAX_TIMES = 20; + let cur = 0 + while (cur < MAX_TIMES){ + cur++; + console.log(cur) + } + ``` + +- `do while` + + ```javascript + do { + cur ++; + console.log(cur); + }while (cur < MAX_TIMES) + ``` + + - 和`while循环`有什么区别? + + `do while`一定先执行一遍代码块的表达式; + +- `for in` + + > 遍历对象的属性 + + ```javascript + let myObj = {a: 1, b:2, c:3, d:4} + for (let e in myObj){ + console.log(e, myObj[e]); + } + a 1 + b 2 + c 3 + d 4 + + ``` + +- `for of` 用的较多 + + > 遍历可迭代对象的元素 + + ```javascript + let myArray = [1, 2, 3, 4, 5] + for (let e of myArray){ + console.log(e); + } + ``` + + - 常见的可迭代对象有哪些? (数组、集合、字典、字符串、) + + - Array + + - Set + + - Map + + - String + + - arguments + + ```javascript + function foo(a, b){ + console.log(arguments); + } + + foo(1, 2) + ``` + +- `forEach` **用的最多** + + ```javascript + let myArray = [1, 2, 3, 4, 5] + myArray.forEach(function (e){ + console.log(e * e); + }) + ``` + + ![image-20210514193556758](C:\Users\yunqin\AppData\Roaming\Typora\typora-user-images\image-20210514193556758.png) + + + +# 条件语句 + +- 一个简单的判断语句 + + ```javascript + for(let i=0; i<100; i++){ + if (i%2===0){ + console.log("偶数", i) + }else if(i < 0){ + console.log("负数不判断") + }else{ + console.log("奇数", i) + } + } + ``` + +- 逻辑运算符 + + - `==` + + 对比操作数是否相同, 操作数会尝试进行类型转换后的比较, **不推荐做为比较符号.** + + ```javascript + '1' == 1 + > true + + false == 0 + > true + ``` + + - `===` + + 严格等于 + + ```javascript + '1' === 1 + > false + + false === 0 + > false + ``` + + - `!` + + 逻辑取反 + + ```javascript + for(let i=0; i<100; i++){ + // 注意运算优先级的问题, 不能写成!i%2 + if (!(i%2)){ + console.log("偶数", i) + }else if(i < 0){ + console.log("负数不判断") + }else{ + console.log("奇数", i) + } + } + ``` + + - `&&` 和`||` + + - `&&`表示AND + - `||`表示OR + +# 选择语句 + +- `switch case` 多条件判断 + + ```javascript + function foo(arg){ + switch (arg){ + case 'a': + console.log(arg, 1); + break; + case 'b': + console.log(arg, 2); + break; + case 'c': + console.log(arg, 3); + break; + default: + console.log('default') + } + } + + foo('e') + ``` + +# 异常处理 + +```javascript +try{ + 表达式 +}catch (e){ + 表达式 +}finally{ + 表达式 +} +``` + +- 一个基本的异常捕获 + + ```javascript + function foo(){ + try{ + throw TypeError('test'); + }catch (e){ + console.log('Error', e); + }finally{ + console.log('Done!') + } + } + + foo() + ``` + +- 处理具体的异常 + + > 处理具体的异常, 只能通过if条件语句来进行类型判断 + + ```javascript + function foo(){ + try{ + throw TypeError('test'); + }catch (e){ + if (e instanceof TypeError){ + console.log("TypeError") + }else{ + console.log('Error', e); + } + }finally{ + console.log('Done!') + } + } + + foo() + ``` + +- 抛出异常 + + `throw`可以抛出任意对象, 让`catch`去捕获 + + ```javascript + function foo(){ + try{ + throw {'a':1}; + }catch (e){ + if (e instanceof TypeError){ + console.log("TypeError") + }else{ + console.log('Error', e); + } + }finally{ + console.log('Done!') + } + } + + foo() + ``` + + + + + +课后作业 + +- 熟悉JS的循环语句并理解其中的异同; +- 熟悉JS的条件语句和逻辑运算符; (===和圆括号) +- 熟悉异常捕获和理解`throw`; \ No newline at end of file diff --git "a/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\257\271\350\261\241\345\222\214\347\261\273\343\200\201\346\236\204\351\200\240\345\207\275\346\225\260\345\222\214this\345\216\237\345\236\213\351\223\276\345\274\217\347\273\247\346\211\277-19-2noteyun.md" "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\257\271\350\261\241\345\222\214\347\261\273\343\200\201\346\236\204\351\200\240\345\207\275\346\225\260\345\222\214this\345\216\237\345\236\213\351\223\276\345\274\217\347\273\247\346\211\277-19-2noteyun.md" new file mode 100644 index 00000000..b5c8ea9f --- /dev/null +++ "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\257\271\350\261\241\345\222\214\347\261\273\343\200\201\346\236\204\351\200\240\345\207\275\346\225\260\345\222\214this\345\216\237\345\236\213\351\223\276\345\274\217\347\273\247\346\211\277-19-2noteyun.md" @@ -0,0 +1,218 @@ +19-2noteyun + +对象和类、构造函数和this原型链式继承-19-2noteyun + + + +# 对象和类 + +> js当中其实没有明确的类的概念, js当中的类只是**创建对象的模板**. 它的本质还是一个特殊的函数 +> +> `class`关键字只是一层封装了原型链的语法糖, 但是方便我们理解. + +- 声明类 + + ```javascript + class Rectangle { + constructor(height, width) { + this.name = 'rectangle'; + this.height = height; + this.width = width; + } + } + ``` + +- 创建对象/实例 + + ```javascript + let rectangle = new Rectangle(2, 5); + console.log(rectangle) + ``` + +- 类方法 + + - 构造方法 + + `constructor`是一种用来**创建和初始化**`class`创建的对象; + + - 实例方法 + + ```javascript + class Rectangle { + constructor(height, width) { + this.name = 'ractangle'; + this.height = height; + this.width = width; + } + + getArea(){ + return this.height * this.width; + } + } + ``` + + - 静态方法 + + ```javascript + static staticMethod(){ + console.log("calling static method") + } + ``` + + - `getter`和`setter` + + ```javascript + get area(){ + return this.getArea() + } + + set area(value){ + this._value = value + } + + //调用: + console.log(ractangle.area) + ``` + +- 类继承 + + ```javascript + class Square extends Rectangle { + constructor(a) { + super(a, a); + this.name = 'square' + } + } + + let suqare = new Square(10) + console.log(suqare.area) + ``` + +- 私有方法和属性 + + 通过`#`来声明一个私有方法或者属性, 只允许类内部调用 + + ```javascript + class Square extends Rectangle { + // 私有属性需要事先进行声明 + #new_name + constructor(a) { + super(a, a); + this.#new_name = 'square' + } + + get new_name(){ + return this.#getName() + } + + #getName(){ + return this.#new_name + } + } + + console.log(square.new_name) + ``` + +# 构造函数和this + +> 在JS中通过构造函数来创建对象的场景更多, 而不是通过class + +- 声明一个构造函数 + + ```javascript + function Rectangle(height, width){ + this.name = 'rectangle'; + this.width = width; + this.height = height; + + this.getArea = function (){ + return this.height * this.width + } + } + ``` + +- 创建对象/实例 + + ```javascript + let rectangle = new Rectangle(10, 2) + console.log(rectangle.getArea()) + ``` + +- 通过`call`方法继承 + + 第一个参数是要绑定的对象, 其他参数代表调用**函数**的参数. + + > `call`方法将`Rectangle`下的属性和方法绑定到`this`上去 + > + > 这里的this指代的就是实例化的square对象 + + ```javascript + function Square(a){ + Rectangle.call(this, a, a); + this.name = 'square' + } + ``` + + - apply + + 和`call`方法几乎没有区别, 只是传入的参数的方式不同; apply传递的是**参数列表;** + + ```javascript + function Square(a){ + Rectangle.apply(this, [a, a]); + this.name = 'square' + } + ``` + +- this + + 不能简单地认为`this`指向的就是实例对象. + + 可以简单地认为谁调用该函数, `this`就指向谁. + +# 原型链式继承 + +在传统面向对象编程中, 我们继承的实现方式都是在创建实例时, 将类中定义的属性和方法都复制到实例中去. + +但是JS中继承是在对象/实例和它的构造器之间创立一个链接, 这个链接就是`__proto__` + +- 原型链 + + 在`js`中每个构造函数拥有一个原型对象`prototype`, 对象从原型继承方法和属性. 而当前对象继承的原型对象可能也有原型, 这样就形成了一条原型链 + + ```javascript + square.__proto__.__proto__.__proto__ + ``` + + - `__proto__`和`prototype`的区别? + + `__proto__`是每个对象/实例都有的属性, 而`prototype`只是构造函数的属性. + +- 原型链式继承 + + 当前对象/实例square找不到getArea方法时, 会继续在原型链中寻找. + + ```javascript + function Square(a){ + this.height = a; + this.width = a; + this.name = 'square' + } + + Square.prototype = new Rectangle() + let square = new Square(10) + console.log(square.getArea()) + ``` + + ![image-20210515160442689](C:\Users\yunqin\AppData\Roaming\Typora\typora-user-images\image-20210515160442689.png) + +![image-20210515160609281](C:\Users\yunqin\AppData\Roaming\Typora\typora-user-images\image-20210515160609281.png) + + + +课后作业 + +- 熟悉三种继承方式和区别;(类继承extends;构造函数继承call、apply;原型链式继承proto__) +- `call`和`apply`的作用; () +- `this`的指向问题; (谁调用该函数,this指向谁) +- 练习原型链式继承;() \ No newline at end of file diff --git "a/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\274\202\346\255\245JS\343\200\201callbacks\357\274\210\345\274\202\346\255\245\345\233\236\350\260\203\357\274\211\343\200\201promise\343\200\201asyncwait-19-3noteyun.md" "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\274\202\346\255\245JS\343\200\201callbacks\357\274\210\345\274\202\346\255\245\345\233\236\350\260\203\357\274\211\343\200\201promise\343\200\201asyncwait-19-3noteyun.md" new file mode 100644 index 00000000..d53e3933 --- /dev/null +++ "b/\347\254\254\344\272\214\346\234\237\350\256\255\347\273\203\350\220\245/5\347\217\255/5\347\217\255_\344\272\221/week19/\345\274\202\346\255\245JS\343\200\201callbacks\357\274\210\345\274\202\346\255\245\345\233\236\350\260\203\357\274\211\343\200\201promise\343\200\201asyncwait-19-3noteyun.md" @@ -0,0 +1,277 @@ +19-3-noteyun + + + +异步JS、callbacks(异步回调)、promise、async/wait + + + +# 异步JS + +JS引擎只是浏览器中的一个线程, 所以在JS当中没有线程和进程的概念.JS的高性能是通过一个基于**事件循环**的异步并发模型来完成. + +JS的性能很高; + +- **事件循环** + + 在页面环境中, 我们移动鼠标, 点击页面元素或者执行一段JS, 都可以认为当前是一个消息. 当前的消息会被丢进一个**无限循环**的消息队列当中, 每一个消息都关联着用来处理这个消息的**回调函数** + + ```javascript + document.addEventListener("click", function(e){console.log(e)}) + ``` + + image-20210516102003255 + + 点击click一下,就会有反应; + + + + - 事件循环的伪代码 + + ```javascript + while(queue.waitForMessage()){ + queue.processNextMessage(); + } + 等到了这个事件,一旦触发,就调用、再触发、再调用; + ``` + + - 消息的执行 + + - JS在执行同步消息任务时, 会执行至完成. + - JS在执行异步消息任务时, 遇到异步操作, 会将该消息丢回消息队列, 等待下一次调度执行. + + (接到同步任务,就开始执行,直到完成) + + (接到异步任务,将其放在队列中,等待被调度在执行。) + + + +# callbacks(异步回调) + +最常见于浏览器的监听事件, 本质就是**将回调函数做为参数**传递给后台执行的其他函数, 其他函数在执行完毕后自动调用回调函数 + +```javascript +document.addEventListener("click", function(e){console.log(e)}) +``` + +为什么还有下面的promise和async,回调地狱 + +- 回调地狱 (像一个圆锥形) + + ```javascript + // 银行转账的伪代码 + transferAccount(cash, + dealCash(cash, function(cash_status){ + authAccount(cash_status, function(order){ + transferStart(order, function(status){ + sendSMS(status) + }, transferExceptionCallback) + }, authExceptionCallback) + }, cashExceptionCallback) + ) + + 要传递多少钱,cash; transferAccount + 钱够还是钱不够,能不能转? cash_status; 处理cash,dealCash() + 能转,那还需要输入密码,authAccount + 正式进行转账,transferStart,转账成功,发送一条信息,sendSMS() + (参数、回调函数,失败的函数exception) + ``` + +# Promise 最常用 + +`Promise`是一个对象, 它代表了一个异步操作的最终**完成**或者**失败**的结果. + +![img](https://i.im5i.com/2021/03/14/hiRQ2.png) + +- 声明一个简单的`promise`对象 + + ```javascript + let promiseObjj=new Promise().then() + let promiseObjj=new Promise().then(result=>{console.log("result",result)}) + let promiseObjj=new Promise((resolve,reject)=>{}).then() + let promiseObjj=new Promise((resolve,reject)=>{ + setTimeout(()=>{resolve("success");reject("failed");},3*1000) + }).then() + ``` + + ```javascript + // =>匿名函数的简写 + let promiseOjb = new Promise((resolve, reject) => { + setTimeout(() => { + resolve("success"); + reject("failed"); + }, 3*1000) + }).then(result => {console.log("result => ", result)}) + + console.log(promiseOjb) + ``` + + ```javascript + let promiseObj=new Promise((resolve,reject)=>{ + setTimeout(()=>{ + resolve("success"); + reject("failed"); + },3*1000) + }).then(result=>{console.log("result=>",result);return true}).then(result=>{console.log("result=>",result)}) + + console.log(promiseObj) + + // Promise { } + // result=> success + // result=> true + + ``` + + pend:在等待中 + + fulfill完成 + + reject 拒绝 + + + +- `promise`的状态 + + - pending + + 初始状态, 表示未接收到结果 + + - fullfill + + 已兑现, 表示操作成功完成 + + - reject + + 已拒绝, 表示操作失败 + +- 在使用`promise`时, 需要注意以下约定 + + - 回调函数时在当前事件循环结束后自动调用的; + - 通过`then`添加的回调函数不管异步操作是否成功都会执行; + - 通过调用多次`then`可以添加多个回调函数, 他们按插入顺序依次执行, 这个方式就叫做**链式调用**; + +- 在`promise`中处理异常 + + - 声明一个简单的xhr请求 (XHR) + + ```javascript + function xhrRequest(url){ + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function(){resolve(xhr.responseText)}; + xhr.onerror = () => reject(xhr.status); + xhr.send() + }).then(result=>{console.log("SUCCESS", result)}) + .catch(error=>{console.log("FAILURE", error)}) + } + + xhrRequest("http://www.baidu.com") + xhrRequest("https://www.baidu.com") + xhrRequest("https://www.baidu.com/asdfasdf/") + ``` + + - 当前环境下, 客户端请求到达了服务端, 服务端也正常地返回了结果. 那么不管状态码是200还是404, 都算是一次成功的请求, 所以结果由`then`回调进行处理, 而不是`catch`. 如果有需要可以自己通过状态码判断后执行不同的流程. + + - 链式调用 + + ```javascript + function xhrRequest(url){ + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function(){resolve(xhr.responseText)}; + xhr.onerror = () => reject(xhr.status); + xhr.send() + }).then(result=>{console.log("SUCCESS", result); return result}) + .then(result=>{console.log("SUCCES 2", result)}) + .catch(error=>{console.log("FAILURE", error)}) + } + + //两个then(),一个catch() + ``` + + - 不管当前链式调用有多长, 异常都会进到`catch`回调函数当中. `catch`也可以进行链式调用, 但是一般一个函数只有一个`catch`回调函数. + + **在console中调用:** + + ```javascript + function xhrRequest(url){ + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function(){resolve(xhr.responseText)}; + xhr.onerror = () => reject(xhr.status); + xhr.send() + }) + } + + p=xhrRequest("https://www.baidu.com") + + ``` + + image-20210516140559292 + + image-20210516140716836 + + ![image-20210516140924574](C:\Users\yunqin\AppData\Roaming\Typora\typora-user-images\image-20210516140924574.png) + + + +# async/await + +``` +async`本质就是将函数转换为`promise +``` + +- 通过`async`和`await`等待完成结果 + + ```javascript + function xhrRequest(url){ + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function(){resolve(xhr.responseText)}; + xhr.onerror = () => reject(xhr.status); + xhr.send() + }) + } + + async function requestBaidu(url){ + let result = await xhrRequest(url); + console.log("DONE!", result) + } + ``` + +- 异常处理 + + ```javascript + function xhrRequest(url){ + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function(){resolve(xhr.responseText)}; + xhr.onerror = () => reject(xhr.status); + xhr.send() + }) + } + + async function requestBaidu(url){ + try{ + let result = await xhrRequest(url); + console.log("DONE!", result) + }catch (e){ + console.log("FAILURE", e) + } + } + + xhrRequest("https://www.baidu.com") + requestBaidu("https://www.baidu.com") + ``` + +image-20210516144102179 + +课后作业 + +- 理解JS的异步; +- 练习课上三种异步实现方式; \ No newline at end of file -- Gitee