如何理解JavaScript中的继承

1、原型链
将一个实例的属性和方法给予到另一个实例的原型上

举个例子:这样你可以看到这两个构造函数出来 两个都是独立的

function Father(){
    
    
    this.name = "巧乐兹"
    this.hobbies = "爱吃巧乐兹"
}
function Son(){
    
    
    this.age = "一根四块五"
}

然后我们将其连接起来

function Father(){
    
    
    this.name = "巧乐兹"
    this.hobbies = "爱吃巧乐兹"
}
function Son(){
    
    
    this.age = "一根四块五"
}

Son.prototype = new Father()
var wxy =new Son()
console.log(wxy.name)

执行结果:你可以看到我们打出wxy 的name 属性就是 我们上面Father 的属性
在这里插入图片描述
但是它也有缺点 :

(1)当我们创建了多个实例之后,我们一旦更改了一个实例的属性之后,那其他的实例的属性也会被修改,因为他们是共享的;
(2)当我们创建子类实例的时候,无法向父类构造函数传递参数

2、借用构造函数
相当于是复制了一份父类的属性 然后将其借用给子类
下面在举个例子:

function Father(){
    
    
    this.name = "巧乐兹"
    this.hobbies = "可爱多"
}
function Son(){
    
    
    this.age = "一根四块五"
    Father.call(this)
}

var wxy =new Son()
console.log(wxy.hobbies)

执行结果:这样我们的 Son 对象里 也拥有了 Father 的属性
在这里插入图片描述

这种方式解决了上面 一旦一个 子类实例 属性更改之后,导致其他子类的属性被一起更改 的情况。
并且该种方式,在创建子类实例时,可以向父类构造函数传递参数

缺点:

无法实现复用,每一个子类实例都有一个新的函数,如果实例对象多了,就会导致内存消耗过大。

3、组合继承
组合继承就是将 上面的两种方式结合起来 ,可以达到取长补短的效果
下面在举个例子:

function Father(name,hobbies){
    
    
    this.name = name
    this.hobbies = hobbies
}
function Son(name,hobbies){
    
    
   Father.call(this,name,hobbies)
}

var wxy =new Son("可爱多","巧乐兹")
console.log(wxy.hobbies)

执行结果:就是说把原型链跟借用构造函数的方法取长补短
在这里插入图片描述
当然 既然是两种方式取长补短之后形成的 一种方式,那么它的优点具有:

(1)不存在共享属性,一个实例属性更改导致其他实例属性更改的情况。 (2)它可以传递参数 (3)方法可复用

缺点 :

子类原型上会有一份 多余的父类实例的属性

4、原型式继承
用一个函数来生出一个新的对象,相当于这个对象就是复制的上一个对象,只不过是利用函数的形式来进行复制。

//我们创建一个dx对象
var a = {
    
    
  
          name : "巧乐兹",
          age : "爱吃"
      }
      
//这个是用来生成 新对象的函数		
   var a = {
    
    
  
          name : "巧乐兹",
          age : "爱吃"
      }
      
//这个是用来生成 新对象的函数		
      function fn(b){
    
    
          //首先里面需要一个构造函数
          function Fn(){
    
    
              
          }			
        Fn.prototype = b;		  
        return new Fn();
      }
      
      var wxy = fn(a);
      
      console.log(wxy.age,wxy.name);

执行结果:这样相当于你便创造出来了一个新的对象 a
你可以弹出它的名字 同样是“爱吃巧乐兹”
在这里插入图片描述

这种方式有其优点也有其缺点

优点 : 它是从已有的对象繁衍出来的新的对象,不需要创建自定义类型
缺点: (1)因为它们是共用的一个地址,那么有一个属性改变,那么会影响所有的对象相同的属性进行改变。
(2)无法实现代码复用,因为属性是后添加的,没用到函数封装。

5、寄生式继承
寄生式继承 首先会创建一个新的对象,然后可以为其(添加属性或方法),然后返回对象

function yy(obj){
    
    
    //创建一个构造函数
      function yy(){
    
    

      }
      yy.prototype = obj
      return new yy()
}
//开始寄生创建一个新的对象 并且为其添加新的属性和方法
function tt(obj){
    
    
    //a 是我们声明的参数
    var a  = yy(obj)
    //添加一个新属性
     a.name = "巧乐兹"
     
     return a
     //返回我们创建的属性
}
//创建一个新的对象
function Fx(){
    
    
this.age  =  "四块五"
}
//那么 新的对象po 既继承了 原对象 的 agr 属性 也被添加了上面的 name 属性
var po = new tt(new Fx())
console.log(po.name)

6、寄生组合式继承
寄生组合式继承就是将两种方式进行结合

function fn(obj){
    
    
			
    function Fn(){
    
    
        
    }
    Fn.prototype = obj;
     return new Fn();			 
}

function Dx(){
    
    
    this.name = "巧乐兹";
    this.age = "爱吃"
}

function Dx2(){
    
    
    Dx.call(this)
}


var obj1 = fn(Dx.prototype0);
obj1.constructor = Dx2;
Dx. prototype = obj1;

var obj2 = new Dx2()

console.log(obj2.age);

优点:修正了上面组合继承的缺点,只使用了一次构造函数
缺点:就是写着十分繁琐

猜你喜欢

转载自blog.csdn.net/Rick_and_mode/article/details/108501141