ES5,ES6中的继承

ES5中的继承:

1,借助构造函数实现继承;(只能实现部分继承)

原理:通过call()函数改变this指向,将父类属性挂载到子类实例中;

 function Parent() {
    this.name = "Parent"
}
function Child() {
    Parent.call(this)
    this.age = 12
}
console.log(new Child())

总结:优点:只调用一次父类的构造函数,避免了在子类原型中创建不必要的,多余的属性;原型链保持不变;

缺点:只能实现部分继承,如果父类属性都在构造函数中,则能实现全部继承,如果父类原型对象上还有方法,子类不能继承;

2,借助原型链实现继承;

原理:将子类的prototype属性赋值为父类实例对象,则子类的__proto__属性继承父类;

function parent(){
	this.name = "parent"
	this.age = 99
}
parent.prototype.say = function() {
	console.log("I an parent")
}
function child(){
	this.sing = "中国"
}
child.prototype = new parent()
console.log(new child())

优点:父类的方法得到了复用;

缺点:重写子类的原型等于父类的一个实例,如果父类 包含引用类型的属性,那么子类所有实例都会共享该属性;

3,组合继承:

 function parent3() {
        this.name = 'parent3';
        this.play = [1, 2, 3];
    }
 function child3() {
        parent3.call(this);
        this.type = 'child3';
    }
// 父类实例赋值给子类原型
child3.prototype = new parent3();
    var p3 = new child3();
    var p4 = new child3();
    console.log(p3.play, p4.play);
    p3.play.push(4);
    console.log(p3,p4);
    console.log(p3.play, p4.play);

优点:继承了构造函数继承和原型链继承的优点,摒弃了缺点,复用了方法,子类又有各自的属性;

缺点:父类构造函数执行了两次,子类的原型对象中也有一份父类的实例属性,而这些属性会被子类实例的属性覆盖掉,也存在资源浪费;

4,组合继承的优化一;

function parent(){
    this.name = "parent";
    this.age = "89"
}
function child(){
    parent.call(this)
    this.play = "pingpang"
}
// 将父类的原型指向子类的原型
child.prototype = parent.prototype
var c1 = new child()
var c2 = new child()
console.log(c1,c2)

instanceof 和 constructor 都是用来判断一个实例对象是不是这个构造函数的实例的。 不同点是:用constructor 比instanceof 更严谨,例如如果 A 继承 B,B 继承 C,A 生成的实例对象,用 instanceof 判断与 A、B、C 的关系,都是 true。所以无法区分这 个到底是 A、B、C 谁生成的实例。而constructor 是原型对象的一个属性,并且这个属 性的值是指向创建当前实例的对象的。

5,组合继承的优化2---寄生组合继承

function parent5() {
        this.name = 'parent5';
        this.play = [1, 2, 3];
    }
    function child5() {
        parent5.call(this);
        this.type = 'child5';
    }
    child5.prototype = Object.create(parent5.prototype);
    child5.prototype.constructor = child5;
    var p7 = new child5();
    var p8 = new child5();
    console.log(p7, p8);
    console.log(p7.constructor);

  组合继承的缺点就是在继承父类方法的时候调用了父类构造函数,从而造成内存浪费,并且找不到实例对象真正的 constructor 。

   那在复用父类方法的时候,使用Object.create方法也可以达到目的,没有调用父类构造函数,并将子类的 prototype.constructor 属性赋值为自己本身,则问题完美解决。

 

ES6: 中的继承:通过class关键字来定义一个类,且类名首字母大写; class之间通过使用extends关键字实现继承,子类必须在constructor方法中调用super;

  class Animal {
        constructor(name = 'John Doe', species = '物种') {
            this.name = name;
            this.species = species;
        }
        sayHello() {
            console.log('hello', this.name, this.species)
        }
    }
    class Sheep extends Animal {
        constructor(name = 'Jimmy', species = '羊') {
            super(name, species);
        }
        sayHello() {
            console.log('child');
            super.sayHello()
        }
    }
    let sheep = new Sheep('Tom');
    sheep.sayHello();

内容可能有所不全,请各位大神指正;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值