js的六种继承

1.原型继承
    核心:将父类的实例作为子类的原型(并不是把父类中的属性和方法克隆一份一模一样的给子类,而是让子类父类之间增加了原型链接)
   特点:父类中私有的和公有的都继承到了子类原型上(子类公有的)
    缺点:如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象

2.借用构造继承,call继承       【不能继承原型链的方法】
    核心:使用父类的构造函数来增强子类实例
    特点:把父类私有的属性和方法,克隆一份一样的给子类私有的属性,Father执行的时候,把Father的中的this换成Son的实例,由于并不是new Father,所以Father.prototype上的属性无关
    缺点:但没有原型,则复用无从谈起

3.混合模式继承: 原型继承+call继承
    核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
    特点:把父类私有的和公有的都变成了子类共有的,但是调用了【两次父类构造函数】,生成了两份实例
    原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承

// 父类
function Father(name) {
    // 属性
    this.name = name || 'father',
        // 实例方法
        this.sleep = function() {
            console.log(this.name + "正在睡觉");
        }
}
// 原型方法
Father.prototype.look = function(book) {
        console.log(this.name + "正在看:" + book);
    }
    // --------------------------------------------
    // 1.原型继承
    // 核心:将父类的实例作为子类的原型(并不是把父类中的属性和方法克隆一份一模一样的给子类,而是让子类父类之间增加了原型链接)
    // 特点:父类中私有的和公有的都继承到了子类原型上(子类公有的)
    // 缺点:如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象
function Son() {}
Son.prototype = new Father(); //相当于重写了Son的原型
Son.prototype.constructor = Son; //重写原型后把Son原型上的constructor重新指向Son
var son = new Son();
son.sleep() //---------father正在睡觉
son.look('TV') //-------------father正在看:TV
console.log(son) //----------------Son {}  【原型链继承并不是克隆一份】
console.log(Father.prototype.isPrototypeOf(son)) //----------true【在原型链上面】
console.log(son instanceof Son) //---------true
console.log(son instanceof Father) //-------true
    // ----------------------------------------------
    // 2.借用构造继承,call继承       【不能继承原型链的方法】
    // 核心:使用父类的构造函数来增强子类实例
    // 特点:把父类私有的属性和方法,克隆一份一样的给子类私有的属性,Father执行的时候,把Father的中的this换成Son的实例,由于并不是new Father,所以Father.prototype上的属性无关
    // 缺点:但没有原型,则复用无从谈起
function Son2() {
    Father.call(this);
    // 可以加参数
}
var son2 = new Son2();
son2.sleep(); //--------father正在睡觉
// son2.look('TV');-------没有原型链的方法,会报错
console.log(son2) //----------Son2 { name: 'father', sleep: [Function (anonymous)] }   【不能继承原型链上的方法,所以没有原型链方法】
console.log(Father.prototype.isPrototypeOf(son2)) //-----------false    【原型链还是】
console.log(son2 instanceof Son2) //----------------------------true
console.log(son2 instanceof Father) //--------------------------false     【不能继承原型链上的方法,所以没有原型链方法】
    // ----------------------------------------------
    // 3.混合模式继承: 原型继承+call继承
    // 核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
    // 特点:把父类私有的和公有的都变成了子类共有的,但是调用了【两次父类构造函数】,生成了两份实例
    // 原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承
function Son3(name) {
    Father.call(this)
    this.name = name
}
Son3.prototype = new Father(); //父类实例作为子类原型,实现函数复用
Son3.prototype.constructor = Son3;
// 【调用了两次构造函数】
var son3 = new Son3('son3');
son3.sleep() //son3正在睡觉
son3.look('TV') //son3正在看:TV
console.log(son3) //---{ name: 'son3', sleep: [Function (anonymous)] }
console.log(Father.prototype.isPrototypeOf(son3)) //-----------------true 【父类原型链上有】     
console.log(son3 instanceof Son3) //-----------------------true
console.log(son3 instanceof Father) //---------------------true

// --------------------------------------------------------------
// 4.原型式继承
// 创建一个函数,将参数作为一个对象的原型对象
function fun(obj) {
    function Son4() {}; //构造函数
    Son4.prototype = obj; //对象的原型对象
    return new Son4(); //
}
var son4_1 = fun(Father);
var son4_2 = fun(Father);
console.log(son4_1) //Function {}
console.log(Father.prototype.isPrototypeOf(son4_1)) //false 
console.log(son4_1 instanceof Father) //false
console.log(son4_1 instanceof fun) //false
    // 创建一个函数fun,内部定义一个构造函数Son
    // 将Son的原型对象设置为参数,参数是一个对象,完成继承
    // 将Son实例化后返回,即返回的是一个实例化对象
    // 优缺点:跟原型链类似
    // ------------------------------------------------------
    // 5.寄生继承
    // 创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象。
    // 可以理解为在原型式继承的基础上新增一些函数或属性
    // (1)原型式继承
function Createobj(obj) {
    function Son5() {};
    Son5.prototype = obj;
    return new Son5();
}
// 上面CreateObj函数 在ECMAScript5 有了一新的规范写法,Object.create(ob) 效果是一样的 , 看下面代码
var son5_1 = Createobj(Father);
var son5_2 = Object.create(Father);
console.log(son5_1.name); // Father
console.log(son5_2.name); // Father
// (2)开始寄生继承
function Jicheng(obj) {
    // var newobj = Createobj(obj); 两种方式都可以
    var newobj = Object.create(obj); //写了这个就可以不用上面的了
    newobj.sayName = function() {
            console.log("我的名字" + this.name);
        } //增强对象
    return newobj; //指定对象
}

var son5_3 = Jicheng(Father);
son5_3.sayName()

// 6.寄生组合

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值