• 构造函数的继承


    今天介绍一下对象之间继承的五种方式

    下面有两个构造函数:

    function Animal(){
      this.species = "动物";
    }
    function Cat(name,color){
      this.name = name;
      this.color = color;
    }

    现在我们怎么使得Cat继承Animal?

    以下我们用五种方法来实现继承

    一、 构造函数绑定(call、apply)

    这种方法直接简单,使用call或apply直接将父对象的构造函数绑定在子对象上

    function Cat(name,color){
      Animal.apply(this, arguments);
      this.name = name;
      this.color = color;
    }
    var cat1 = new Cat("大毛","黄色");
    alert(cat1.species); // 动物

    二、 prototype模式

     javaScript规定,每一个构造函数都会有一个prototype属性,指向另一个对象,而这个对象所有的方法和属性,都会被

    构造函数的实例继承。

    如果Cat的prototype对象,指向Animal的一个实例,那么所有Cat的实例,也就理所当然的能够继承Animal了。

    Cat.prototype = new Animal(); 
    Cat.prototype.constructor = Cat;
    var cat1 = new Cat("大毛","黄色");
    alert(cat1.species); // 动物

    我们来分析一下这段代码。

    Cat.prototype = new Animal();这行代码让Cat的prototype对象指向了一个Animal的实例。

    它相当于完全删除了prototype对象原来的值,然后赋予一个新的值。

    但是,这样会有一个问题出现,就是Cat.prototype,constructor会指向Animal,所以,

    Cat.prototype.constructor = Cat;这行代码让Cat.prototype的constructor指向Cat,不至于导致继承链的紊乱。

    三、 直接继承prototype

    我们可以把Animal对象中不变的属性写入Animal.prototype。这时候,我们就可以直接去Animal.prototype。

    我们将Animal对象改写一下:

    function Animal(){ }
    Animal.prototype.species = "动物";

    然后,将Cat的prototype对象指向Animal的prototype对象。

    Cat.prototype = Animal.prototype;
    Cat.prototype.constructor = Cat;
    var cat1 = new Cat("大毛","黄色");
    alert(cat1.species); // 动物

    虽然这种方法实现了继承,但是,当我们修改Cat.prototype时,会反映到Animal.prototype。

    还有一个问题就是当添加了Cat.prototype.constructor = Cat;这行代码的时候,我们会发现

    Animal.prototype.constructor = Cat,把Animal的constructor 也修改了,所以这种方法不是很完美。

    四、 利用空对象作为中介

    利用一个空的对象作为一个中介

    var F = function(){};
    F.prototype = Animal.prototype;
    Cat.peotorype = new F();
    Cat.prototype.constructor = Cat;

    F是个空对象,几乎不占用内存,这时候修改了Cat.prototype的属性。

    我们将上面的方法,封装成一个函数,便于使用。

    fnntion extend(Child,Parent){
        var F = function(){};
        F.prototype = Parent.prototype;
        Child.peotorype = new F();
        Child.prototype.constructor = Child;
        Child.uber = Parent.prototype;
    }

    使用方法:

    extend(Cat,Animal);
    var cat1 = new Cat("大毛","黄色");
    alert(cat1.species); // 动物

    控对象继承,可以说是一种很完美的继承方法,推荐大家使用。

    五、 拷贝继承

    如果把父对象的所有属性和方法,拷贝进子对象,也能够实现继承。

    首先,还是把Animal的所有不变属性,都放到它的prototype对象上。

    function Animal(){}
    Animal.prototype.species = "动物";

    然后,再写一个函数,实现属性拷贝的目的。

    function extend2(Child, Parent) {
      var p = Parent.prototype;
      var c = Child.prototype;
      for (var i in p) {
        c[i] = p[i];
      }
      c.uber = p;
    }

    使用方法:

    extend2(Cat, Animal);
    var cat1 = new Cat("大毛","黄色");
    alert(cat1.species); // 动物

    非构造函数的继承 

    在最后我又加了一种Jquery里面使用的继承方法。叫做深拷贝方法。

    下面是两个对象

    var Person = {
        nation:"中国",
        place:["美国","英国","法国"]
    }  
    var Superman = {
        name:"超人"
    }

    深拷贝函数封装,它在里面区别了对象和数组两种情况

    function deepCopy(p,c){
        var c = c ||{};
        for(var i in p){
            if(typeof p[i] === 'object'){
                c[i] = (p[i].constructor == Array) ? [] : {};
                deepCopy(p[i],c[i]);
            }else{
                c[i] = p[i];
            }
        }
        return c
    }

    使用方法:

    var Superman = deepCopy(Person);
    console.log(Superman.nation);//中国
    Superman.place.push('日本')
    console.log(Superman.place);
    console.log(Person.place);

    深拷贝的好处就是当你修改子对象的属性的时候不会对父对象的属性有影响。

    目前,jQuery内部实现继承就是采用的这种方法。

  • 相关阅读:
    SQL Server 2008 数据库回滚到某个时间点
    SQL Server 2008以上误操作数据库恢复方法——日志尾部备份
    C# BindingSource
    何谓SQL Server参数嗅探
    mongodb获取具体某一天的查询语句
    给MongoDB添加索引
    MongoDB 学习笔记四 C#调用MongoDB
    Access MongoDB Data with Entity Framework 6
    Ruby 和 OpenSSL CA 证书的问题
    解决方法:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby
  • 原文地址:https://www.cnblogs.com/jannryguo/p/7131279.html
Copyright © 2020-2023  润新知