2021-03-15

Js 对象之间的继承及原型链查找分析

  • Js 对象之间的继承

    • 构造函数的属性继承

    • ①对象拷贝 :使用for....in循环继承父对象属性

      <script>  var student1 = {   name : "lisi",   id : 1213,   meaasge : function(){    console.log(name + "," + id);   }  };  //使用for....in循环继承父对象属性  //封装成一个函数  function student(parent,child){    for (var k in parent) {    if (child[k]) {     continue;//对于student2里独有的要保留的值,则跳过该次循环    }    child[k] = parent[k];   }  }  student(student1,student2);  console.log(student2); </script> 

      上述继承父对象是对象拷贝,实际上继承指的是类型和类型之间的继承,而封装的构造函数就是用来创建类对象的

    • ②原型继承

      //原型继承  function Person(name, age, sex, score) {    this.name = name;    this.age = age;    this.sex = sex;  } //抽象,提取所有的公共属性,放到一个父类型中  function Student(score){   this.score = score;  }  function Teacher(course){   this.crouse = crouse;  }    //原型对象,可以将自己的属性和方法继承给将来的实例对象使用  Student.prototype = new Person("li",21,"male");  //生成一个实例  var s1 = new Student(90);  console.dir(s1);

          原型继承,在没有修改constructor之前,Student是没有自己的constructor属性的,但它有继承Person对象是的constructor属性,它指向的是Person。所以,这里需要人为定义一个constructor属性,指向Student。

       //原型对象,可以将自己的属性和方法继承给将来的实例对象使用  Student.prototype = new Person("li",21,"male");  Studnet.prototype.constructor = Student;  //生成一个实例  var s1 = new Student(90);  console.dir(s1);  console.log(s1.constructor);

    这种继承的缺点是,只能继承一次,不适用属性的继承。

    • ③函数的 call 方法

       //函数的 call 方法  function fn(a,b){   console.log(this);//指向的是window   console.log(a+b);  }  var name = {   name:"li"  };  //普通函数的调用fn(1,1)  //call方法 第一个参数用来指定this,第二个及以后传的是实参。  fn.call(name,3,3);

             函数call ,函数本身就是一种对象,可以有自己的属性和方法。call方法本身就是一种指向函数的方法。

              call方法 在调用函数的时候,有两个功能:①更改函数内部的this指向;②调用函数执行内部代码,其当调用时,第一个参数用来指定this,第二个及以后传的是实参。

    • ④借用构造函数继承属性

             直接对父类型的构造函数进行一个普通调用,在调用的过程中,内部的this指向的是window,通过call方法更改Person内部的this指向调用函数(如,student调用的,使用call方法后,this指向的是student)

      //借用构造函数继承属性  function Person(name, age, sex) {   this.name = name;   this.age = age;   this.sex = sex;  } //抽象,提取所以的公共属性,放到一个父类型中  function Student(name,age,sex,score){   //对父类型进行一个普通调用   Person.call(this,name,age,sex);   this.score = score;  }  function Teacher(name,age,sex,course){   Person.call(this,name,age,sex)   this.crouse = crouse;  }  var s2 = new Student("li",22,"male",90);  console.dir(s2);

    []

    • 构造函数的方法的继承

      for...in继承、原型继承、

      ①for...in继承

        //构造函数的方法继承  function Person(name, age, sex) {   this.name = name;   this.age = age;   this.sex = sex;  } //抽象,提取所有的公共属性,放到一个父类型中  Person.prototype.message = function(){   console.log(123);  }  function Student(name,age,sex,score){   Person.call(this,name,age,sex);   this.score = score;  }  function Teacher(name,age,sex,course){   Person.call(this,name,age,sex)   this.crouse = crouse;  }  //for ..in继承  for(var k in Person.prototype){   //Student保留自己的constructor 不让Studnet继承Person的constructor   if(k == "constructor"){    continue;   }   Student.prototype[k] = Person.prototype[k];  }

      ②原型继承

      //原型继承  Student.prototype = new Person();  //在继承的情况下也不能改变Student的constructor的指向  Student.prototype.constructor = Student;  var s1 = new Student("li",21,"male",91);  s1.message();  console.dir(s1);

      ③组合继承:属性在构造函数内部继承,方法通过原型继承

      //构造函数的方法继承  function Person(name, age, sex) {   this.name = name;   this.age = age;   this.sex = sex;  } //抽象,提取所有的公共属性,放到一个父类型中  Person.prototype.message = function(){   console.log(123);  }  function Student(name,age,sex,score){  //属性的继承,使用call方法继承   Person.call(this,name,age,sex);   this.score = score;  }  function Teacher(name,age,sex,course){   Person.call(this,name,age,sex)   this.crouse = crouse;  }    //方法继承,通过原型继承  Student.prototype = new Person();  //在继承的情况下也不能改变Student的constructor的指向  Student.prototype.constructor = Student;  var s1 = new Student("li",21,"male",91);  s1.message();  console.dir(s1);

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b5YjTJO9-1615779490405)(C:\Users\xiaomi\AppData\Roaming\Typora\typora-user-images\image-20210315112105641.png)]

      通过实例对象本身查找自己原型链的方法,这个方法继承的是Person的方法,再查找new Person()的实例对象的原型对象,查找出它的方法。



Student函数部分的原型图

在这里插入图片描述

完整的原型链查找:

    将Person对象的实例赋值给Student.prototype,所以s1指向的原型对象是Person对象。

    而Person的message()方法则存放在Person的原型对象中,所以s1在调用方法时,首先在自身的方法中查找,没有查找到;继续向原型查找,自己的原型上还没有找到方法;那么原型方法又要在自己的原型上继续查找,找到message()方法。

    如果还未找到,即Person的原型对象上还是没有该方法,则继续想Person原型对象的原型对象查找,查找Object原型对象,若还没有,则查找错误。
在这里插入图片描述









原文转载:http://www.shaoqun.com/a/627667.html

跨境电商:https://www.ikjzd.com/

c88:https://www.ikjzd.com/w/1017

taofenba:https://www.ikjzd.com/w/1725


Js对象之间的继承构造函数的属性继承①对象拷贝:使用for....in循环继承父对象属性<script>varstudent1={name:"lisi",id:1213,meaasge:function(){console.log(name+","+id);}};//使用for....in循环继承父对象属性//封装成一个函数functionstu
法瑞儿:https://www.ikjzd.com/w/412
沃尔玛:https://www.ikjzd.com/w/220
敦煌网站:https://www.ikjzd.com/w/189
索要评论简单范本,实用干货分享:https://www.ikjzd.com/home/6301
那个亏了300万的亚马逊卖家,犯了什么错?:https://www.ikjzd.com/home/134772
卖家慌了!亚马逊更改算法?差评置顶销量狂跌:https://www.ikjzd.com/home/132033

No comments:

Post a Comment