史上最全的继承方式 - 原型继承、中间类继承、call 继承、寄生组合继承、class继承

继承方式:

  • 原型继承: 继承私有和公有;
  • 中间类继承: 继承公有属性;
  • call 继承: 继承私有属性;
  • 寄生组合继承: 继承公有和私有属性;
    上面四种属于原生JS中的继承方式;
  • class继承:ES6中的继承
  1. 原型继承
    通过类A new出来的实例覆盖了B的默认原型的空间地址,那么通过类B创建的实例既可以使用类A实例的私有属性,也可以调用类A原型上的公有属性;类B继承了类A公有和私有属性,这种继承方式就是原型继承

原型继承的写法

function A() {
}
function B() {
}
B.prototype=new A;  
var b = new B;

例子:

function A() {
	this.getX=function () {
		console.log(100);
	}
	function getY() {
	}
}
A.prototype.haowan=function () {
	console.log("天下雨了快")
}
function B() {
}
B.prototype=new A;
var b = new B;
b.haowan();
b.getX();

在这里插入图片描述


  1. 中间类继承
function sum() {
	// 把arguments中__proto__指向了数组Array 的原型;那么arguments就可以通过__proto__找到数组中原型中的方法,并且使用;
	// 在IE10及以下,不兼容;
	arguments.__proto__ = Array.__proto__; //或者写成:arguments.__proto__ = [];
	arguments.pop();
	//console.log(arguments);
}
sum(12,3,5,66,77,33);

  1. call 继承
    call 继承只继承私有属性;
function A() {
	this.x = 100;
	this.getX = function () {        
	}
}
function B() {
	this.z = 1; //this指b,B的实例;
	A.call(this); //改变A中的this指向,指向类B的实例,让A函数运行
}
var b = new B;  //类B继承了类A的私有属性,不能使用类A的公有属性;所有类B创建的实例,都可以使用类A的私有属性;
console.log(b);

  1. 寄生组合继承
    继承公有和私有属性
function A() {
            this.x = 100;
        }
        A.prototype.getX = function () {
            
        }
        function B() {
            A.call(this); 
        }
        // 让B的原型中的__proto__指向A的原型;那么通过类B创建的实例;既可以使用A的私有属性,也可以使用公有属性;
        B.prototype = Object.create(A.prototype); //不能写成B.prototype = A.prototype,是因为写这样的话修改B的prototype,A的prototype也会被修改;
        B.prototype.getY = function () {  //给B的原型上添加方法时,A的原型不变;
            }
        var b = new B;  
        console.log(b.constructor);// A

[外链图片转存失败(img-tV5qg5MQ-1568820786275)(./A8F41DD2-FDB5-4FB4-9D6C-74AFC71E72DA.png)]

  1. Class继承
    ES6中的class继承
    Class 可以通过extends关键字实现继承;
    继承了类的公有属性和私有属性;

Class继承的写法:

class A {}

class B extends A {
  constructor() {
    super(); //在子类constructor中必须加上super();
  }
}

上面代码中,子类B的构造函数之中的super(),代表调用父类的构造函数,用来新建父类的this对象。
如果子类没有定义constructor方法,这个方法会被默认添加

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。

class Point {
	constructor(x, y) {
	    this.x = x;
	    this.y = y;
	 }
}

class ColorPoint extends Point {
	constructor(x, y, color) {
		  this.color = color; // ReferenceError
		  super(x, y);
          this.color = color; // 正确
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值