子类继承父类的属性和方法(原生继承,call继承,寄生组合继承,ES6中class类继承)
原生继承:让子类的原型指向父类的一个实例
function A(){this.x = 100;}
A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
function B(){this.y = 200;}
B.prototype = new A();
var f = new B();
原型图
1、方式:B.prototype = new A();A的实例本身具有父类A的私有属性和公有方法,子类B的原型指向它,那么子类B的实例就可以找到这些属性和方法
2、和传统后台语言继承不一样,子类继承父类,并不是把父类属性和方法克隆一份给子类,JS中的原型继承是让子类和父类建立原型链的机制。
存在问题:子类可以重写父类原型上的方法(重写),子类和父类还是有关系
父类的私有属性和公有属性都变为了子类实例的公有属性
子类原型上的属性和方法,重新执行父类实例后,之前的方法都没有了类的继承封装和多态
call继承:把父类A作为普通函数执行,让A中的 this 变为B的实例,相当于给B的实例增加一些属性和方法
function A(){this.x = 100;}
A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
function B(){A.call(this);this.y = 200;} //让A执行,让A中的this变为f
var f = new B();
存在问题:把父类A当作普通函数执行,和父类原型没关系,只是把A中的私有属性变为子类B实例的私有属性,A原型上的公有属性方法和B以及它的实例没有关系
寄生组合继承:A的私有变为B的私有,A的公有变为B的私有
function A(){this.x = 100;}
A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
function B(){A.call(this);this.y = 200;} //基于call把A的私有变为B的私有
//B.prototype = A.prototype; //一般不这样处理,这种模式可以轻易修改父类原型的上的东西,会导致A的实例也受影响
B.prototype = Object.create(A.prototype);
var f = new B();
原型图
这种方法和原型继承的唯一区别:
B.prototype = new A()
创建的A的实例虽然指向了A的原型,但是实例中不是空的,存放了A的私有属性,这些属性成为了B的公有属性
B.prototype = Object.create(A.prototype)
好处是创建了一个没有任何私有属性的空对象,指向A的原型,这样B的公有属性中不会存在A的私有属性
扩展:Object.create()
:内置Object
类自带方法的作用:
1、创建一个空对象
2、让新建的空对象的__proto__
指向第一个传递进来的对象(把传递进来的对象做为新创建的空对象的原型)
ES6中的类和继承:
ES6创建类标准语法,这种语法创建出来的类只能 new 执行,不能作为普通函数执行
class Fn{
constructor(n,m) {
// 等价于传统ES5类的构造体
this.x = n;
this.y = m;
};
getX(){}; // 给Fn的原型上设置方法(只能设置方法不能设置属性)
static AA(){}; // 把Fn当作普通对象设置私有方法,不能设置属性
}
let f = new Fn(10,20);
继承方法:
class A{constructor() {this.x = 100;};getX(){}}
class B extends A{constructor() {super();this.y = 200;};getY(){}} // 类似于call继承,super中传递的实参都是给A的constructor传递
let f = new B()
- 封装:把实现一个功能的代码进行封装,主要目的是‘低耦合高内聚
- 多态:
a、重载:方法名相同,参数的个数或者类型不同,名字相同的方法叫做重载(后台语音中才有重载),JS中不能存在重载
b、重写:字类重写父类方法
c、继承
网友评论