手记

【学习打卡】第六天 直面JavaScript中的30个疑难杂症

学习课程名称:直面JavaScript中的30个疑难杂症
章节名称:面向对象(重难点)
讲师姓名:公明2020


课程内容概述

  1. 面试高频如何理解面向对象
  2. 带你图解原型和原型链
  3. 开发中如何使用继承
  4. 开发中如何运用 Object.defineProperty()方法

理解面向对象

面向对象的三大特征:封装、继承、多态。

成员属性和方法,公开、私有、静态
公开:在外使用对象.属性或方法名,可以被自由的调用和继承

私有:对内不对外,使用对象.属性或方法名,无法被调用,但在类中的所有方法可以自由的访问它;也无法被继承

静态:静态属性和静态方法,是属于构造函数的,只能通过类名.属性或方法声明的,无法通过实例获取

在JavaScript中,私有属性和方法都是通过作用域模拟的,在ES2022中加入了#字段来表示私有属性和方法。

封装
因为对象需要对自己负责,对象的很多东西都不需要或者不可以暴露给外部。

所以,封装的主要作用是解决数据的安全性,内在也体现了“每个对象对自己负责”的原则。

方法的封装:就是将方法私有化,同时需要提供用于设置和读取的set/get方法,让外部使用我们提供的方法

属性的封装:属性私有化,同时需要提供用于设置和读取的set/get方法

继承
主要目的是为了解决代码的复用

实现代码的复用有两种方式:组合 和 继承

那么什么时候该用组合?什么时候该用继承呢?

多态
同一个操作,作用于不同的对象,会产生不同的结果。

即发出一个相同的指令后,不同的对象会对这个指令有不同的反应。

好处:灵活、解耦

耦合度:模块和模块之间,代码和代码之间的关联度

紧耦合就是它们之间的关联度大,代码很难维护,很容易出bug,而且出现一个bug,其他bug很可能像滚雪球一样增长,猝不及防。

多态性,要求我们面向接口编程。

TS 中我们可以定义一个方法不去实现,并且将这个方法置为抽象方法,当时我们的类也就必须为抽象类了,在前面添加 abstract 字段。然后让子类继承的时候去继承并实现这个方法(子类中也必须要包含这个抽象类中的抽象方法)

JS中每一个函数都有一个prototype属性,这个属性指向函数的原型对象,每一个由原型对象派生的子对象,都有相同的属性。子对象就叫构造函数,从实例原型中获取相同的属性。

原型链继承

让一个构造函数的原型是另一个类型的实例,那么这个构造函数new出来的实例就具有该实例的属性。

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

借用构造函数实现继承

在子类型构造函数的内部调用父类型构造函数;使用 apply() 或 call() 方法将父对象的构造函数绑定在子对象上。

优点:解决了原型链实现继承的不能传参的问题和父类的原型共享的问题。

缺点:借用构造函数的缺点是方法都在构造函数中定义,因此无法实现函数复用。在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。

组合继承

将 原型链 和 借用构造函数 的组合到一块。使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性

原型式继承

借用构造函数在一个函数A内部创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。

本质上,函数A是对传入的对象执行了一次浅复制。

寄生式继承

寄生式继承的思路与(寄生) 原型式继承工厂模式 似, 即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。

ES6、Class实现继承

原理ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。 ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this


0人推荐
随时随地看视频
慕课网APP