13-Class与Promise

98 阅读6分钟

1.class

问题: 旧js中,构造函数和原型对象是分开定义的。不符合"封装"概念

解决: 今后,只要在es6中创建一种新的类型,包含构造函数+原型对象方法,都要用class来创建

什么是class: 程序中专门集中保存一种类型的所有子对象的统一属性结构和方法定义的程序结构。

如何定义class: 3句话:

  • 用class{}包裹原构造函数+原型对象方法

  • 原构造函数名升级为整个class的名字,所有构造函数统一更名为"constructor"

  • 原型对象中的方法,不用再加prototype前缀,也不用=function,直接简写为: 方法名(){ ... ...}

    直接放在class{}内的方法定义,其实还是保存在原型对象中的。

如何使用class: 和使用旧的构造函数完全一样:

var 对象名=new class名(属性值,...);

本质: 新瓶装旧酒,换汤不换药:

  • 构造函数中的属性,依然会成为子对象的自有属性
  • 直接定义在class中的方法,依然保存在子对象的原型对象中
  • 子对象依然使用_ proto _指向原型对象

class.jpg

问题: 如果多个子对象共用的相同的属性值,应该放在那里?

旧js中,是和共有方法一起放在原型对象中

ES6 class中:

问题: 虽然直接在class中定义的方法,都默认保存在原型对象中。但是直接在class中定义的属性,却不会成为共有属性,不会保存在原型对象中。而是成为每个子对象的自有属性

解决: 为了和其它主流开发语言尽量一致,ES6的class放弃了在原型对象中保存共有属性的方式。而是改为用静态(static)属性保存!

  • 什么是: 不需要创建子对象,单靠类型名就可直接访问的属性,就称为静态属性

  • 何时: 今后,在ES6中,如果希望所有子对象,都可使用一个共同的属性值时,都要用静态属性代替原来的原型对象属性

  • 如何定义静态属性:

    class 类型名{
    	static 共有属性名=属性值
    	...
    	...
    }
    
    

**原理:**标有static的静态属性,都是保存在构造函数对象身上。因为构造函数在程序中不会重复!所以,静态属性,也不会重复!任何是否,任何地点,访问一个类型的静态属性,永远访问的都是同一份!

class1.jpg

class.jpg 两种类型间的继承:

问题: 两种class之间包含部分相同的属性结构和方法定义

解决: 两种class类型间继承

如何: 2大步:

额外创建一个父级class,2件事:

i. 父级class的构造函数中包含子类型class中相同部分的属性结构定义

ii. 父级class的原型对象中包含子类型class中相同部分的方法定义

iii. 既然父级class中保存了相同的属性结构和方法定义,则子类型class中,就可以删除所有重复的属性结构和方法定义

iv. 问题: 子类型class的子对象缺少必要的属性,而且有些共有方法也无法使用了!

让子类型class继承父类型的class,2步:

i. 设置子类型的原型对象继承父类型的原型对象:

   class 子类型 extends 父类型{ ... }

原理: 只是设置子类型的原型对象继承父类型的原型对象,只能保证孙子对象可以使用爷爷类型原型对象中的共有方法!暂时无法为孙子对象补全缺少的自有属性.

ii. 使用super关键字,调用爷爷类型的构造函数。

原理: super是专门指向爷爷类型构造函数的关键字。调用super()等于爷爷类型的构造函数。调用爷爷类型的构造函数,等效于执行爷爷类型的构造函数中共有的"this.xx=xxx"语句,即可为孙子对象弥补缺少的共有属性结构。

结果:

孙子对象可使用3处保存的方法: 自己的,父级class的,爷爷class的

孙子对象中拥有两处规定的属性:父类型构造函数+爷爷类型构造函数。

class2.jpg

class3.jpg

问题1: extends?inherit是继承的意思。但是,为什么用extends表示继承?
答: 继承是为了更好的扩展,程序中的继承,都是为了在继承现有成员的基础上,进一步扩展出自己个性化的新成员!所以,程序中的继承,都用extends(扩展)
问题: super? 为什么指向父类型构造函数的关键字,称为super?
答: super在数学中指超集,所有的猫,是一个集合,所有的老虎,也是一个集合,但是,我们还可以用一个更大的集合“猫科动物”,来包含猫集合和老虎集合。这个可以包含猫集合和老虎集合的更大的集合“猫科动物”,就称为超集,英文为super

2.Promise(承诺)

什么是: 专门保证多个异步任务必须顺序执行的一种特殊变成方式

为什么:

问题: 在实际开发中,经常需要让多个异步任务顺序执行

错误: 单纯先后调用多个异步函数

原因: 异步函数各自执行各自的,互不干扰,互相之间也不会等待。

不好的解决: 利用回调函数

promise1.jpg

问题: 如果要先后执行的任务多了!就会形成很深的嵌套结构——回调地狱。极其不优雅,极其不便于维护

好的解决: 今后,只要多个异步任务必须顺序执行时,都要用promise技术来代替回调函数方式

A定义前一项任务时:

promise3.jpg

B.连接前后两个异步任务:

前一项任务().then(后一项任务)

强调: 之后的任务一定不要加(),加()表示立刻执行。而我们不希望后边的任务立刻执行

promise2.jpg

Promiss对象三大状态:

  • 当异步任务执行过程中,整个new Promise()对象处于pending(挂起)状态
  • 当异步任务成功执行完,调用成功的开关函数时,整个new Promise()对象切换为fulfilled(成功)状态,new Promise()会自动调用.then()执行下一项任务
  • 当异步任务执行出错,调用失败的开关函数时,整个new Promise()对象切换为rejected(出错)状态,new Promise()会自动调用.catch()执行错误处理代码

其实,行业内:

  • 正确的开关: resolve 同意继续
  • 失败的开关: reject 拒绝继续