js 对象创建及其继承的方法

   重新看红皮书,觉得很多知识多看几遍确实是能看的更明白些。今天重温了一下对象创建和继承,就稍微记下来,巩固一下。

   js是面向对象的编程语言,ECMA-262吧对象定义为:“无序属性的集合,其属性可以包含基本值,对象或者函数”。每个对象都是基于一个引用类型创建的,这个引用类型可以是原生类型,也可以是自定义的。

    一,讲讲创建对象的几个方法

      1. var person = new Object(); 

      2. var person = {};

      3. 工厂模式

      4. 构造函数模式

      5. 原型模式

      6. 组合使用构造函数模式和冤案型模式

      7. 动态原型模式

      8.等等......

     这里着重记一下构造模式和原型模式,毕竟之后的模式和继承方法都是由于这两个的优缺点借鉴而来。

     4.构造函数模式     

        function Person(name,age,job){
          this.name = name;
          this.age = age;
          this.job = job;
          this.sayName = function(){
            console.log(this.name);
          };
        }
        var person1 = new Person('niko','19','FE');

        这种方式创建对象,可以将它的实例化标识为一中特定类型。及实例可以通过 instanceof 或者constructor 来检测对象的类型。缺点是无法完成方法的复用,即每个方法都需要在实例化上重新创建。

      5.原型模式

        我们自然是希望创建对象时可以共享某些属性和方法,搞这个原型模式挺拿手的~~~来露个脸。简单的说,我们创建的每个函数都有一个prototype属性,这个prototype属性是一个指针,指向一个对象,这个对象里面放着创建的这个对象实例的原型对象。原型对象,即是包含所有实例都共享的属性和方法。默认情况下,所有原型对象都自动获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针。绕来绕去估计就晕了,来个图解释一下。

    

   通过原型模式创建对象之后,是可以顺顺利利的完成属性和方法的共享,但是也是有弊端的如果包含引用类型的值,那么实例化的某一个对象对这个值进行操作,就会修改原型里的值,这样问题就比较麻烦了。所以组合模式就出现了,及用构造函数来创建属性,用原型模式来创建共享方法。

    7.动态原型模式,就是把所有信息封装到函数里看着会简洁好多,也是组合了构造函数和原型模式的优点,在函数内部初始化原型(仅仅在第一次运行时初始化)。

      

      function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        if(typeof this.sayName!= "function"){
          Person.prototype.sayName = function(){
          console.log(this.name);
          };
        }

      }
      var person1 = new Person('niko','19','FE');

      跟组合模式不同的是,初始化原型在函数内部,并且如果有多个共享函数时,只判断一个就好~~看着简洁那么一小丢~~对象创建就写到这,接下来写一下继承啦啦啦啦~

  二,常见的继承方式

    1.原型链

    2.借用构造函数

    3.组合继承

    4.组合寄生式继承

    5.原型式,寄生式..

    挑几个重要的讲吧,重要的就是掌握原型链的原理,以及构造函数继承方式,组合是采取了这两个优缺点进行优化,组合寄生则是针对组合继承进行的优化。原型、寄生式是对一个相对的对象来创建另一个,没怎么碰到就不讲了。

    1.原型链

      原型链的主要思想就是让一个引用类型继承另一个引用类型的实例。原型对象将包含一个指向另一个原型的指针,另一个原型中也包含指向另一个构造函数的指针。层层递进之后,形成原型链。

      

    function SuperType(){
      this.property = true;
    }
    SuperType.prototype.getSuperValue = function(){
      return this.property;
    };
    function Subtype(){
      this.subproperty = false;
    }
    Subtype.prototype.getSubValue = function(){
      return this.subproperty;
    }
    Subtype.prototype.getSubValue = function(){
      return this.subproperty;
    };
    var instance = new Subtype();

      

    啊,写到一半突然要闭馆了闭馆了闭馆了=.=泪奔一下 ,中间详细就不解释了,看懂这个图就没啥大问题了~原型链的问题就是,共享引用类型值的时候,修改一个实例就会修改原型。

   2.借用构造函数

    这个方法就是在子类构造函数中调用超类的构造函数。

  

    function SuperType(name){
      this.name = name;
    }
    function SubType(){
      SuperType.call(this,'niko'); //在this的作用域中调用SuperType()
    }
    var instance = new SubType();

这种方式不像原型继承,相当于在子类的作用域中吧超类的属性完完全全复制了一份。因为不是引用的指针,所以,即使是引用类型的属性值,每个实例都会复制一份属性值,所以不会有什么问题哒~~~而且借用构造函数模式可以在子类中传参。

    3.组合继承就是兼顾了原型模式和借用构造函数模式的优缺点。既可以共享方法,也可以让不同的实例分别有自己的属性。

        

      function SuperType(name){
        this.name = name;
        this.colors = ['red','blue','orange'];
      }
      SuperType.prototype.sayName = function(){
        console.log(this.name);
      }
      function SubType(name,age){
        //继承属性
        SuperType.call(this,name); //第二次调用SuperType()
        this.age = age;
      }
      
      SubType.prototype.sayAge = function(){
        console.log(this.age);
      }

      //继承方法

      SubType.prototype = new SuprType(); //第一次调用SuperType();
      var instance = new Subtype('niko',34);

          

        如图所示,第一次调超类的时候,SubType.prototype得到两个属性:name,colors。调用Subtype构造函数时,第二次调用超类,在新对象上创建实例属性:name,colors。这两个实例属性屏蔽了原型中的属性。

      这种方法可以达到既可以共享方法,也可以有自己的实例属性,但是调用两次超类的构造函数。

    4.寄生组合式继承

      为了解决组合式的缺点,寄生组合式这个超级大Boss上场了。

        大体思路还是借用构造函数来继承属性,用原型链的混成方法机场方法。与组合 方式不同的是,没有在子类中调用超类,而是取得了一个超类的副本。

      

      function inhertiPrototype(subType,superType){
        var prototype = object(superType.prototype); //创建对象
        prototype.constructor = subType; //增强对象
        subType.prototype = prototype; //指定对象
      }

      

 

 

 

 

 

 

 

 

 

posted @ 2015-07-12 13:27  echo_yaonie  阅读(162)  评论(0编辑  收藏  举报