什么是面向对象?

面向对象是一种编程思想

JS本身是基于面向对象构建出来的,例如JS中有很多的内置类,向promise就是ES6中新增的一个内置类,我们可以基于new Promise来创建一个实例,来管理异步编程,我在项目中,promise也经常用,也研究过它的源码。。

我们平时使用的vue,jquery等也是基于面向对象的,它们都是类,可以通过创建她们的实例来操作他们

JS中的面向对象和其他编程语言略有不同,JS中的类和实例是基于原型和原型链机制来处理的,而且js中关于类的重载、继承也和其他语言不一样

封装

低耦合高内聚,可复用性强

多态

重载

方法名相同,形参个数或者类型不一样 => Js中不存在真正意义上的重载

JS中的重载指的是同一个方法,根据传参不同,实现出不同的效果

重写

在类的继承当中,子类可以重写父类中的方法

继承

子类继承父类中的属性和方法,目的是让子类的实例能够调用父类中的属性和方法

原型继承

让父类的属性和方法再子类实例的原型链上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function A (x) {
this.x = x
}
A.prototype.getX = function () {
console.log(this.x);
}
B.prototype = new A(200) // B的原型指向A的实例
B.prototype.constructor = B
function B (y) {
this.y = y
}
B.prototype.getY = function () {
console.log(this.y);
}
let b1 = new B(100)
console.log(b1.y); // 100
console.log(b1.x); // 200
b1.getY(); // 100
b1.getX() // 200

特点

  1. 不向其他语言一样中继承(其他语言一般是拷贝继承,也就是子类继承父类,会把父类中的属性和方法拷贝一份到子类,供子类实例调用),他是把父类的原型放到子类实例的原型链上,实例想调取这些方法是基于__proto__原型链查找机制完成的
  2. 子类可以重写父类上的方法(这样会导致父类其他的实例也受到影响)
  1. 父类中私有或者公有的属性方法,最后都会变为子类中公有的属性和方法

Call继承

​ 子类方法中把父类当作普通函数来执行,让父类中的this指向子类的实例,相当于给子类实例设置了很多私有属性或方法

  1. 特点:
    • 只能继承父类私有的属性或方法(由于把父类当作来执行,和其原型上的属性和方法无关)
    • 父类私有的变成子类私有的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function A (x) {
this.x = x
}
A.prototype.getX = function () {
console.log(this.x);
}

function B (y) {
A.call(this, 200) // b1.x = 200
this.y = y
}
B.prototype.getY = function () {
console.log(this.y);
}
let b1 = new B()
console.log(b1.x);

寄生组合继承

Call继承 + 类似于原型继承

父类私有和公有属性方法分别是子类实例的私有和公有属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function A (x) {
this.x = x
}
A.prototype.getX = function () {
console.log(this.x);
}

function B (y) {
A.call(this, 200) // b1.x = 200
this.y = y
}
// Object.create(obj) => 创建一个空对象,让空对象的__proto__指向obj
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B;
B.prototype.getY = function () {
console.log(this.y);
}
let b1 = new B()
console.log(b1.x);
/**
若不兼容Object.create方法,可以自定义一个该方法
Object.create = function (obj) {
function Fn () {}
Fn.prototype = obj
return new Fn()
}
*/

ES6中的继承简单认识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ES6中的继承
class A {
constructor (x) {
this.x = x
}
getX () {
console.log(this.x);
}
}
// => B.prototype.__proto__ = A.prototy
class B extends A {
constructor (y) {
super(200) // super() => A.call(this)
this.y
}
getY () {
console.log(this.y);
}
}
let b1 = new B(100)
console.log(b1);