继承、封装、多态
- 封装:把实现某个功能的代码进行封装处理,后期想实现这个功能,直接调用函数执行即可,"高内聚、低耦合"
- 继承:子类继承父类的方法,子类的实例即拥有子类赋予的私有/公有属性方法,也想拥有父类赋予的私有/共有属性方法
- 多态: 多态包括重载和重写
- 重载:后端语言中的重载,指的是「方法名相同,参数类型或个数不同,这样会认为是多个方法」
- 重写:子类重写父类中的方法
原型继承
特点:和传统后台语言中的继承不一样「后台:子类继承父类,会把父类的方法 cp 一份给子类」,并没有把父类的方法 cp 一份给子类,而是建立子类原型和父类之间的原型链指向,后期子类实例访问父类中提供的属性方法,也是基于 __proto__ 原型链一层层查找。
// 存在的问题:
// @1 父类想要赋予其实例私有的属性 x,此时变成了子类实例 ys 的公有属性
// @2 子类实例可以基于原型链,访问父类的原型对象,这很怪异 (ys.__proto__.prototype)
function Parent() {
this.x = 100;
}
Parent.prototype.getX = function() {}
function Child() {
this.y = 200;
}
Child.prototype = new Parent;
Child.prototype.getY = function() {}
let ys = new Child;
console.dir(ys);
call 继承
把父类当初普通方法执行「原型就没作用了」,让方法中的 this 是子类的实例,这样可以达到让父类中赋予其实例私有的属性,最后也变成子类实例的私有属性。
解决了原型继承的问题 1
// 存在的问题:
// @1 子类实例可以基于原型链,访问父类的原型对象,这很怪异 (ys.__proto__.prototype)
function Parent() {
this.x = 100;
}
Parent.prototype.getX = function() {}
function Child() {
Parent.call(this);
this.y = 200;
}
Child.prototype = new Parent;
Child.prototype.getY = function() {}
let ys = new Child;
console.dir(ys);
call + Object.create 组合式继承「推荐」
这样就只能通过 __proto__ 原型链来访问父类原型了。
function Parent() {
this.x = 100;
}
Parent.prototype.getX = function() {}
function Child() {
Parent.call(this);
this.y = 200;
}
// 创建一个对象作为子类的原型链 对象的原型链指向 Parent.prototype
Child.prototype = Object.create(Parent.prototype);
Child.prototype.getY = function() {}
let ys = new Child;
console.dir(ys);
es6 extends 继承「非常类似于寄生组合继承」
class Parent {
constructor() {
this.x = 100
}
getX() {}
}
class Child extends Parent {
constructor() {
super();
this.y = 200;
}
getY() {}
}
let ys = new Child;
console.dir(ys);