一.js高级(3)-原型及其继承

二. 原型

  1. 更好的解决方法: prototype

                  Js 规定每个函数都有 prototype 属性,指向一个对象;这个对象的所有属性和方法都被函数所拥有,这就意味着我们可以把构造函数对象的属性和方法直接定义在prototype上

 

                   构造函数和原型 和实例对象之间的关系

                            1) Person.prototype.constructor == Person

                            2)实例对象中有一个指针__proto__ 指向 构造函数 prototype

                                     Instance.__proto__ == Person.prototype

                            3)实例对象直接或间接继承构造函数的所有属性和方法

 

  1. 原型链

    当代码读取某个对象的方法时,都会执行一次搜索:

    现在自己身上找,找不到就到原型上找

  1. 原型对象的使用建议

    a)         私有成员(一般是非函数成员)放在构造函数中

    b)         共有成员(函数成员)放在原型对象对象中

    c)         手动重置 constructor 属性

        function Person(name ,age){

                 this.name = name;

                 this.age = age

        }

          Person.prototype ={

                   Constructor: Person,

                   Type: “human”,

                   sayHello: function(){

                             console.log(this.name)

             }

          }

         三.继承

javascript中实现继承的方式:

1) 对象与对象之间的继承-》  对象的拷贝  
   存在的问题: 对象与对象之间无法实现 数据类型 的继承 
  

    var wjl = {
    name: '王健林',
    money: 10000000,
    cars: ['玛莎拉蒂', '特斯拉'],
    houses: ['别墅', '大别墅'],
    play: function () {
    console.log('打高尔夫');
    }
  }

    var wsc = {
    name: '王思聪'
    }

    function extend(parent, child) {
    for (var key in parent) {
      // 不给wsc复制同名的属性
      if (child[key]) {
        continue;
      }
      child[key] = parent[key];
      }
    }

     extend(wjl, wsc);

    console.dir(wsc);
    wsc.play(); //打高尔夫

              2)属性继承: 

                            function student(name,age){

                                      Person.call(this,name,age);

        }

    存在的问题: 借用构造函数  无法继承父类型构造函数原型中的 方法

    3)拷贝继承:

      Person.prototype.sayName = function(){

               Cnonsole.log(“sayHello”);

      }

 

                   function Student(name,age){

                            Person.call(this,name,age);

      }

     For(var key in Person.prorotype){

             Student.prototype[key] = Person.prototype[key];

      }

    存在的问题:
       如果子类型重新对自身的 原型对象进行了修改 会影响 父类型的原型 ,一般情况使用比较少,主要用于对 对象方法的继4) 组合继承(构造函数+原型函数):

             function Student(name,age){

                  Person.call(this,name,age);

        }

        //让子类型的原型指向 父类型的实例对象, 继承父类型的方法, 同时不影响父类型的原型对象, 这样有第二个子类型继承父类型的时候, 原型对象不会改变

        Student.prototype = new Person();

        //如果不修改constructor, 正常情况下,不会影响使用; 只在一种情况下会产生影响: 在不知道 student1 是由哪个函数实例化出来的情况下,想要复制一个:
           var student2 = student1.constructor();
        Student.prototype.constructor = Student;           //exam就是 Student 的独有方法, 不会影响父类型以及其他的子类型         Student.prototype.exam = function() {           console.log("考试");         }         var nora = new Student('nora', 25);         实例对象nora调用 sayName 方法时, 先在 实例Nora本身上找这个方法; 发现没有,继续在Nora的原型对象上找(由于我们已经把Student         的原型对象改为一个Person实例),发现 Person实例上仍然没有这个方法, 所以继续在 Person实例的 原型对象上找; 找到此方法,调用;

        //原型对象和实例对象中的 constructor
           //constructor指向的不是实例化实例的构造函数,而是实例化该对象的构造函数的原型的构造函数
          console.log(Student.prototype.constructor === nora.constructor)   //true
          console.log(nora.__proto__.constructor === nora.constructor) //true
     
          nora 可以通过 .__proto__.constructor 获取; 也可以通过 nora.constructor 获取
          Student 只能通过 .prototype.constructor 获取;
posted @ 2018-12-12 14:49  noraZhang  阅读(187)  评论(0编辑  收藏  举报