0%

OOP与继承

2023/12/4 OOP 与继承

  • 器:工具,JS,VUE,React…
  • 术:用前端做了什么项目。React 设计了什么,针对了什么问题,解决了什么
  • 道:知识体系 -> 以道驭术

什么是面向对象 Object-oriented Programming

Java -> 一切皆对象

:1.属性 2.方法
对象是类的实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//面向过程
init()
whitePlay()
repaint()
check()

//面向对象
const checkerBoard = new CheckerBoard()
const whitePlayer = new Player('white')
const blackPlayer = new Player('black')

whitePlayer.start()
checkerBoard.repaint()
checkerBoard.check()

blackPlayer.start()

whitePlayer.rollback()

JS 中的面向对象

JS 中创建一个对象,有哪些方法?

1
2
3
var baz = Object.create({}) //baz.__proto__.__proto__ === Object.prototype
var bar = {} //bar.__proto__ === Object.prototype
var p = new Person()

Object.prototype
OATdaG.jpg
Object.prototype 是所有对象的原型对象,所有对象都有这个属性
Object.prototype.constructor 指向 Object

思考:如何用 Object.create 创建一个对象实现 var bar={}一样的效果

1
var foo = Object.create(Object.prototype)

proto本质是原型链关系

JS 这门语言本质设计的时候就是原型链关系
A.proto === B
A 上没有的方法就从 B 上找,如果 B 上有我就用 B 的

new 关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
function Person(name, age) {
this.name = name
this.age = age
}

const p = new Person('L', 35)

// 1.new创建了一个对象,这个对象的原型指向了构造函数的原型
p.__proto__ === Person.prototype
// 2.Person有个原型,原型上有个constructor是Person自己
Person.prototype.constructor === Person
// 3.p这个对象是构造函数创造的,p的构造是Person
p.constructor === Person

new 关键字到底干了什么?

  • 创建了一个对象
  • 这个对象的原型指向了这个 Person/Function 的 prototype
  • 该对象实现了 Person 的方法
  • 根据一些特定的情况返回对象
    • 如果这个函数没有返回值,或者返回一个对象类型,则 new 最后返回创建的这个对象(p)
    • 如果这个构造函数明确返回了一个对象(return{}),则返回这个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 实现new
function newFunc(Person, ...rest) {
if (typeof Person !== 'function') {
throw new Error('Person必须是一个函数')
}
var obj = Object.create(Person.prototype)
var result = Person.apply(obj, rest)
return result && typeof result === 'object' ? result : obj
}
// 实现Object.create
function inherit(p) {
if (p === null) throw TypeError()
if (Object.create) {
return Object.create(p)
}
if (typeof p !== 'object' && typeof p !== 'function') throw TypeError()

function f() {}
f.prototype = p
return new f()
}

继承

继承描述类和类之间的关系

原型继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Parent(name) {
this.name = ['lei', 'yu']
}

Parent.prototype.getName = function () {
return this.name
}

function Child() {}
Child.prototype = new Parent()
Child.prototype.constructor = Child

// 1.child不传参
// 2.如果Parent有属性是引用类型,一旦修改了所有的都受影响

构造函数继承

1
2
3
4
5
6
7
8
9
10
11
function Parent(name) {
this.name = name
}
Parent.prototype.getName = function () {
return this.name
}

function Child(name) {
Parent.call(this, name)
//调用Parent函数,并传递当前对象作为参数,以继承Parent函数的属性和方 法。
}

组合继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Parent(name) {
this.name = name
}
Parent.prototype.getName = function () {
return this.name
}

function Child(name) {
Parent.call(this, name)
//调用Parent函数,并传递当前对象作为参数,以继承Parent函数的属性和方 法。

// 问题:我只想构成一个原型链关系
Child.prototype = new Parent()
Child.prototype.constructor = Child
}

组合寄生式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Parent(name) {
this.name = name
}
Parent.prototype.getName = function () {
return this.name
}

function Child(name) {
Parent.call(this, name)
//调用Parent函数,并传递当前对象作为参数,以继承Parent函数的属性和方 法。

// Child.prototype = Object.create(Parent,prototype)
Child.prototype = inherit(Parent.prototype)
Child.prototype.constructor = Child
}

OAnbrC.jpg

Q&A

组合寄生和 class 的区别?

Loose 模式应该差不多,主要是以下区别:
Class 继承,会继承静态属性:
子类中,必须在 constructor 中调用 super,因为子类自己的 this 对象,必须先通过父类的构造函数完成

-------------本文结束感谢阅读-------------