JS中继承的几种方式总结,以及原型的理解

先看一张原型图
在这里插入图片描述
1.每一个函数数据类型天生自带一个prototype属性,prototype的属性值是一个对象数据类型的;
2. prototype的属性值天生自带一个constructor属性,constructor属性值指向当前原型所属的类;
3. 每一个对象数据类型天生自带一个__proto__,其属性值指向当前实例所属类的原型

Class继承

class语法

 class Bar{ // 这既不是一个函数的{},也不是对象的{};
        constructor(x,y){
            // 这个的代码就相当于函数体中的代码;
            // 这里面可以新增私有属性
            //this.x=x;
           // this.y=y;
           console.log(x);
           
            var a = 1;
        }
        // 在原型上新增方法;
        getX(){// 这不是箭头函数
            console.log("X");
        }
        getY(){
            console.log("Y");
        }
        static x=1// static可以给类新增私有属性
        y=2// 在给实例新增私有属性
    }
    console.log(typeof Bar)
    //Bar.prototype.x=100;
    console.dir(Bar);
    let a =  new Bar(100,200);
    console.log(a);
    // {x:1,arguments:null,caller:null,prototype:{}}
    // Bar
    
    // console.log(a);
    //var b = Bar();
    //console.log(b);

1.class继承方式

class 继承既继承A的私有属性,又能继承其公有属性;

 class A{
            constructor(){
                this.x =1;
            }
            getX=()=>{
                // 这是一个普通函数
            }
            getY(){
                // 这是一个公有的属性
            }
        }
        
        let a = new A;
        // B的prototype中的__proto指向A的原型
        // class 继承既继承A的私有属性,又能继承其公有属性;
        class B extends A{
            constructor(a){
                super();// super;构造器,继承的函数中想增加自己的私有属性,必须加这个,否则会报错
                this.z=a;
            }
            getZ(){

            }
        }
        let b = new B(1);
        console.log(b);

2.原型继承

让B的原型地址指向A的实例

 function A(){
            this.x=10;
        }
        A.prototype.getX=function(){

        }
        function B(){

        }
        B.prototype=new A;// 让B的原型地址指向A的实例
        var b = new B;
        b.x//b就可以调用A属性上的方法
        b.getX

原型继承练习题

    function A(){
            this.getY = function(){
                console.log(200);
            }
        }
        A.prototype.getX = function(){
            console.log(100); 
        }
        function B(){
        }
        B.prototype.getNum = function(){
            console.log(0);
        }
        var b1 = new B;//b1的__proto__占用了B原有的原型的空间地址,原有的空间地址不能被回收;
        B.prototype=new A;//{getY:f}把A的实例的空间地址给了B的原型;
        // 类B继承类A的私有属性以及公有属性,这种继承方式就是原型继承;
        var b = new B;
        b.getY();
        b.getX();
        b.getNum();
        b1.getNum();
        console.log(b1.constructor) // function B(){}
        console.log(b.constructor); // function A(){}
       
        // b通过__proto__找到B的prototype,里面没有getX,会继续通过prototype中的__ptoto__找到A的prototype;

3.call继承

call继承只能继承私有属性,不能继承公有

 function A(){
        // this--> B的实例
        this.a = 100;
    }
    A.prototype.getA = function(){
        
    }
    function B(){
        // 在类B中,调用了类A,并且通过call改变了类A中的this指向,使其指向B的实例;这样类B创建的实例就具有类A的私有属性;这种继承就是call继承;
        A.call(this);// this --> b
    }
    var b = new B;
    console.log(b);//

4.中间类继承

在IE10以下不兼容的;

function sum(){
            // arguments.pop();// arguments是实参集合;是类数组,是Object构建出来的实例;不能直接调用到Array原型上的方法,arguments.__proto__指向了Object的原型;
        //在IE10以下不兼容的;
            arguments.__proto__=Array.prototype;// arguments是对象只能用__propo__,这种的叫中间类继承
            arguments.pop();
        }
        sum(12,3,4,6,7,44,66,88,9);

5.寄生组合继承

通过b既能找到B的私有和A的公有

 // 寄生组合继承  call 
         Object.create({a:1});//创建对象,会把第一个参当成原型上的原型链
        // 继承了私有和公有;
        //context=Object(context)|| window;
        var  num =1;
        console.log(Object(num));// new Number(1)
        var o = Object.create({a:1})
        console.log(o);
        function A(){

        }
        function B(){
            A.call(this)
        }
        B.prototype = Object.create(A.prototype);
        
        var b = new B;
        console.log(b);//通过b既能找到B的私有和A的公有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值