prototype原型继承

441 阅读3分钟

所有函数只要创建出来,系统都会分配一个原型对象给整个函数,通过prototype可以找到原型对象.

我们创建的每个函数都有一个 prototype(原型)属性。使用原型的好处是可以让所有对象实例共享它所包含的属性和方法。

定义:

1 原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法.原型也是对象.

2 利用原型的概念和特点可以提取共有属性.

3 实例化对象可通过_ _proto__查看原型

原型与对象

概念1

   
       function Person(){
          
       }
      // Person.prototype 原型  祖先
       Person.prototype.age = 18; 
       Person.prototype.say = function(){
           console.log('吃饭了');
       }
       //Person.prototype.age = 22; 
      let p1 = new Person();
      let p2 = new Person();
       console.log(p1);

概念2 、提取构造函数中的公共属性

第一步:
   function Cart(ower,color){
        this.name="BMW";
        this.lang = '3米'
        this.price = 30000;
        this.ower = ower;
        this.color = color;
    }
    let p1 = new Cart();
    let p2 = new Cart();
    console.log(p1);
    console.log(p2);
    console.log(p1===p2);
    此时可以看出构造函数的多次创建会产生多个相同函数,造成冗余太多。
    利用原型prototype解决。回顾prototype
        console.log(Cart.prototype);
    //constructor表示当前的函数属于谁
    //__proto__  ==  [[prototype]],书面用语,表示原型指针
    
第二步:直接使用原型提取公共属性
  //  Cart.prototype.name = "BMW";
  //  Cart.prototype.lang = "3米";
  //  Cart.prototype.price = 30000;
    
    Cart.prototype={
        name:'BMW',
        lang:'3m',
        price:30000
    }
    function Cart(ower,color){
      
        this.ower = ower;
        this.color = color;
    }
    let p1 = new Cart();
    let p2 = new Cart();
    console.log(p1);
    console.log(p2);

概念3 、实例化的对象用__proto__访问原型

 function Cart(own, color) {
      this.name = 'BMW';
      this.lang = '3米';
      this.price = 300000;
      this.own = own;
      this.color = color;
    }

    // 构造函数查看原型  prototype
    console.log(Cart.prototype)
    //实例化对象查看原型  __proto__
    var c1 = new Cart('ls', 'red');
    console.log(c1.__proto__)
原型链继承

JavaScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.

简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针(proto)

原型链的连接点就是 __ proto __

从近的往远的访问.

_ proto _ 是实例对象,拥有对的指向原型的属性,而构造函数是没有的.

       function Person(name){
           this.name = name;
           this.age = 18;
       }
       var zs = new Person('zs');
    // console.log(Fn.prototype.constructor);
      console.log(zs.__proto__); // {constructor: ƒ} Fn的原型
        console.log(zs.__proto__.__proto__.constructor);  //Object
        console.log(zs.__proto__.__proto__.__proto__);  //null

绿色的线表示原型链,当zs实例调用一个属性或者方法时,现在自身找,然后一层一层的向上,直至找到null.没有则返回undefined

原型链的改造

<script>
     Grand.prototype.lastName = 'cheng';
      function Grand(){
      
      }
      var grondObj = new Grand();

      Father.prototype = grondObj;
      function Father(){
         this.name="zs"
      }
      var fatherObj = new Father();
      
       Son.prototype = fatherObj;

      function Son(){
          this.hobbit = 'smoke';
      }
      var sonObj = new Son();
    </script>
  当Son要访问一个属性不存在时,就会找到原型的指针__proto__,然后找到原型继续找
实例属性与原型属性

原型属性的操作

查,即获取数据

删,子孙不能删除,其本身可以删除

改,除非自己增,后辈无法增

增,自己增,后辈无法增