JS本身是基于面向对象开发的编程语言
=》类:封装、继承、多态
1、封装
:类也是一个函数,把实现一个功能的代码进行封装,以实现低耦合高内聚
2、多态
:重载、重写
重写:子类重写父类上的方法(伴随着继承运行的)
重载:相同的方法由于参数和返回值的不同,具备了不同的功能(JS不具备严格意义上的重载)
JS中的重载,同一方法根据传参的不同实现不同的功能;
3、继承
:子类继承父类中的方法
在JS语言中,它的继承和其他编程语言还是不太一样的
JS中的多种继承方式
1)JS中的第一种继承方案:原型继承(让子类的原型=父类的实列
)
Child.prototype=new Parent();//原型继承
子类的实列,能够用子类私有的和原型上公有的
父类的实例,可以使用父类私有和原型上公有的
所以想让子类可以用父类上私有的和公有的,让子类的原型=父类的实列
指向/查找
这种方式继承的特点如下图:
2)JS中的第二种继承方式call继承
在子类中执行执行父类方法并用call改变this的指向
这种方式只能继承父类中私有的,不能继承父类中公共的。
3)JS中的第三种继承方式寄生组合式继承(Call继承+另类原型继承)
我们目标:父类私有变为子类私有,父类公有变成子类公有的
Parent.call(this)
Child.prototype.proto=Parent.prototype;但这种方式 IE不支持
=》Child.prototype=Object.creat(Parent.prototype)
//=>Object.creat(obj)创建一个空对象,让其原型链指向obj)
function Parent(){
this.x=100;
}
Parent.prototype.getX=fungtion(){
return this.x;
}
//Child.prototype=new Parent();//原型继承
//Child.prototype.__proto__=Parent.prototype;//组合继承
//===>
Child.prototype=Object.creat(Parent.prototype)//对象的原型是没有constructor的
Chile.prototype.constructor=Child;//为了保证继承的完整性,手动加上constructor
function Child(){
//在子类构造函数中,把父类当做普通方法执行(没有父类实列,父类原型上的那些东西也就和它没有关系了)
// Parent();
Parent.call(this);//this.x=100;强制给c1这个实列设置一个私有的属性x,属性值100,相当于让子类的实例继承了父类的私有属性,并且会变为了子类私有的属性,“拷贝式”的。
this.y=200;
}
Child.prototype.getY=function(){
return this.y;
}
let c1=new Child;
console.log(c1)//Child {y:200;__proto__:getY}
//创建一个空对象,让其原型链指向obj
//console.log(Object.creat(obj))
ES6中创建类和继承
class Parent{
constructor(){
this.x=100;
}
//相当于Parent.prototype.gexX=function...
getX(){
return this.x
}
}
//继承:extends Parent 这种继承方式类似于寄生组合继承
//注意:继承后一定要在constructor第一行加上super();
class Child extends Parent{
constructor(){
super();//=>类似于我们之前的call继承 super(100,200):相当于把Parent中的constructor执行,传递了100,200
this.y=200;
}
//相当于Parent.prototype.getX=function...
getY(){
return this.y
}
}
//Child()
//ES6中创建的就是类,不能当做普通函数执行,只能new执行
第一种继承方式(原型链继承)
function A(x) {
this.x = x;
}
A.prototype.getX = function () {
console.log(this.x);
};
function B(y) {
this.y = y;
}
B.prototype = new A(200);
B.prototype.constructor = B;
B.prototype.getY = function () {
console.log(this.y);
};
let b1 = new B(100);
b1.y;//不输出 console.log(b1.y);//100
b1.getY();//100
b1.getX();//200
第二种继承方式call
function A(x) {
this.x = x;
}
A.prototype.getX = function () {
console.log(this.x);
};
function B(y) {
A.call(this, 200);
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
第三种继承方式(寄生组合)
function A(x) {
this.x = x;
}
A.prototype.getX = function () {
console.log(this.x);
};
function B(y) {
A.call(this, 200);
this.y = y;
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
B.prototype.getY = function () {
console.log(this.y);
};
let b1 = new B(100);
ES6继承
class A {
constructor(x) {
this.x = x;
}
getX() {
console.log(this.x);
}
}
class B extends A {
constructor(y) {
super(200);
this.y = y;
}
getY() {
console.log(this.y);
}
}
let b1 = new B(100);
console.log(b1);