gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
阅读:4181回复:1

JavaScript原型链与继承内容总结

楼主#
更多 发布于:2020-10-09 14:23
1. JavaScript继承

JavaScript继承可以说是发生在对象与对象之间,而原型链则是实现继承的主要方法;


1.1 原型链

利用原型让一引用类型继承另一个引用类型的属性和方法。
构造函数中有个prototype(每个函数中都有),指向他的原型对象,每个原型对象中也有一个constructor属性,指向原构造函数。通过构造函数创建的新对象中都有一个无法直接访问的[[proto]]属性,使得对象也指向构造函数的原型。这使得对象也获得了原型中的方法和属性。

  • 当访问对象中的属性或方法时,如果对象中没有该属性或方法,则会向上一级原型对象中寻找该属性或方法,如果找了,就返回该属性,若没有则继续向上面的原型中去查找该属性。


    1.2 构造函数的原型链继承




function Father(name,age){
        this.name=name;
        this.age=age;
    }
       Father.prototype.eat=function(){        //给原型添加eat方法
           console.log(this.name+"吃饭了");
       }

       var f1=new Father("李四",20);         //创建新对象f1,    [[proto]]指向父原型
       function Son(){
       }
       Son.prototype=f1;                       //将子构造函数的prototype指向了父类型的对象,这里实现了——继承
          var s1=new Son();      //  创建子对象
    s1.eat();               //李四吃饭了


注意:
①:当 Son.prototype指向Father的时候,他就已经是父类型的Son了。
②:s1.eat();    s1中没有此方法,该方法在父类型原型中,当s1访问时,现在s1中查找,若没有则向他指向的原型中去查找该方法,若还是没有,则继续往上面的原型中查找。这样就形成了一条原型链。
③:通过原型链实现了继承。
简写:

      var f1=new Father;
      var Son.prototype=f1
      //可以直接简写成:
      var Son.prototypr=new Father();      //这个时候可以传值进去 ,其余地方无法传值




1.3 默认顶端原型

默认的顶端原型
  • 是当所有类型都没有指明继承某个类型时,则默认继承Object类型。
  • objec中也有prototype指向他的object原型,object中也有[[proto]],只不过他指向的是null;可忽略。
  • object的很多方法,都是存在object的原型中;
  • 在原型链中查找,从当前位置一直往上访问,直到原型链顶端位置。

1.4 测试数据
  1. typeof 测数据的类型,最好只来测试基本类型数据,应为除了基本类型外全是返回object。
console.log(typeof 123)  //number
console.log(typeof "ccsa ")  //string

  1. console.log(typeof 123)  //number
    console.log(typeof "ccsa ")  //string
  2. instnaceof 测试一个对象属不属于其父类对象的类型

    function  Father(name){
    }
    var f1=new Father();
    console.log(f1 instanceof Father);          //true



3.isPrototypeOf(要测的对象) 专属于原型对象的方法,判断该对象在不在该原型链上,使用:父类构造函数.prototype.isPrototypeOf(对象)


    function Father(){    
    }
    function Son(){    
     }
      Son.prototype=new Father;
      var s1=new son();
      console.log(Father.prototype.isPrototypeOf(s1));   //true
      console.log(Object.prototype.isPrototypeOf(s1));   //true




1.5 借调

借调:借用构造函数调用冒充继承,借调实现的继承,不是真正的继承,只是借用构造函数中的属性或方法。
apply,call。


function Fn(name,age){
      this.name=name;
      this.age=20;
    }
    function Son(name,age,sex){
      Fn.call(this,name,age)                //借调继承Fn;
      this.sex=sex;
    };
    var s1=new Son("李四",20,"男");
    console.log(s1);

注意:借调缺点:call是冒充继承,不是真正的继承,所以不能访问原构造函数的原型中的属性或方法。


1.6 组合继承

组合构造函数的借调继承和原型的继承优点:


function Fn(name,age){
      this.name=name;                           //构造函数的属性多样
      this.age=age;
      if((typeof Fn.prototype.eat)!="funciton"){    //判断语句中是否有该方法,没有则创建
        Fn.prototype.eat=function(){            //原型的方法共享
            console.log(this.name+"吃了饭");
        }
      }
    }

    function Son(name,age,sex){                 //创建子类构造函数
      Fn.call(this,name,age)                //借调Fn()的属性
      this.sex=sex;
    };
    Son.prototype=new Fn();         //Son.prototype指向父类对象,实现了继承,所以能够调用eat方法,
    var s1=new Son("李四",20,"男");    //若没有继承,单单的使用call借调Fn继承,子类实例s1无法调用eat方法
    callconsole.log(s1);            //因为call不是真正的继承
    s1.eat();


注意:Son.prototype=new Fn(); 这条语句 实现了Son继承父类型Fn;Son指向的是父类型创建的对象,而父类型的对象有自己的属性,并且又成为了子类型的原型,那么其中的属性不就成了共享的了吗。 但是前面还有用到Fn.call( ),这条语句已经借调了父类构造函数属性,相当于覆盖了子类型原型的属性。
gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
沙发#
发布于:2020-10-09 14:23
游客


返回顶部