JS中总共有六种继承模式,包括原型链、借用构造函数、组合继承、原型式继承寄生式继承和寄生组合式继承。为了便于理解记忆,我遐想了一个过程,对6中模式进行了简单的阐述。

  很长的一个故事,姑且起个名字叫女娲造人吧。

  创建对象

  女娲一个一个的捏人(创建对象),这样太慢,于是设计了一种机器(函数),想造什么样的,告诉他这个人有哪些特点和功能,机器来制造。这就是工厂模式的(使用同一个接口创建对象,回产生大量重复代码,由此发明了一种函数(模具))。

但是机器造人同样也比较麻烦(挖土、和泥、捏眼睛、捏鼻子...)于是封装的思想来了,鼻子眼睛什么的提前捏好备用,改造机器,告诉要造的人具有什么样的眼睛,鼻子,机器可以直接拿来安装ok,这样的机器就是构造函数

  这样仍然存在问题,假设要让捏的人都能跑,就要机器给每个人安装一个‘跑’的功能,这样工序太慢,还可能出错,找第三方吧(函数方法定义到构造函数外部,全局作用域中)。第三方负责给我把捏的人都装上跑的功能,我拿来再放到机器上用,省的每次都加工。ok,人都能跑了,很方便,但是问题又出现了,造的人还需要‘跳’、‘走’..的N个功能,总不能再找N个第三方吧,那这样建机器就没意义了。于是女娲(开发人员)早创造了原型模式...厉害了我的娲。

  原型模式中每个函数都有一个prototype属性,是指针,指向原型对象。原型对象包含能让所有实例共享的属性和方法,这个原型对象有一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针。

  看似有点绕,从女娲这个角度就好理解了:造物主女娲娘娘还发明了个各种各样的模具(原型对象),要开始造了:1造一类人-->用的是造这类人的模具。  毕竟可以造万物,造什么用什么样的模具。所有造人机器(函数)都有各自唯一的一个模具(原型对象),并且机器有一个标签[prototype],指向模具,这个模具有能贴生产标志的[constructor]属性,指向这个机器,表示是这个机器的模具生产。因此要造什么样的一类人,只需要改模具就好了。这就是原型对象的好处,方便,快捷。

  生产过程如下: 1造机器A :function  jqA(){}; //有个prototype属性,指向模具(原型对象)

          2造模具:jqA.prototype={

            constructor: jqA, //相当于贴上标签,由A机器生产,

            name:'lily',

            skin:'white',

            run: function(){

            alert(this.name+'run');  }

}

           这个模具负责造名字叫lili,皮肤为white,能run的这类人。

          3  造一个这类型的人    var person1=new jqA();

           再造一个这类型的人  var person2=new jaA();

    person1和person2都有一个[[prototype]]属性,表示经过模板A处理了,指向A模板

    很完美,问题又来了,这样生产出来的人都一样,迎面走来五个一模一样的白皮肤窈窕美女,然后又有五个一抹一样的矮挫丑,太可怕了。 所以机器A在用模板的同时,还可以根据女指令来使造的这类人有不同的特点,比如:这个蓝眼睛,那个胖点。。这个额外的功能通过构造函数实现---》组合使用构造函数和原型模式

    生产过程如下:       

//组合使用构造函数模式和原型模式

function  Person(name,skill,country) {

this.name=name;

this.age=skill;

this.country=country;

this.member=["刘封","刘婵"];

} //机器可以听命令

Person.prototype={

constructor:Person,

sayName:function () {

alert(this.name);

}

}  //还可以用模板

var person1=new Person('马超','铁骑','蜀国');

var person2=new Person('刘备','仁德','蜀国');

这时候,女娲懒得照顾机器的同时又照顾模板,所以直接把模板装在了机器中:在构造函数中初始化原型对象---》动态原型模式  更方便了

    生产过程如下:

      

     function  Person(name,skill,country) {

    this.name=name;

     this.skill=skill;

  this.country=country;

if(typeof this.sayCountry !=undefined){

    Person.prototype.sayCountry=function () {

      alert(this.country);

     };

     }

       }

var friend=new Person('张飞','咆哮','蜀国');

friend.sayCountry();

还有问题?ok,提供寄生构造函数模式:机器中加个内部机器,这个内部机器负责生产,并生产的的人提供给外部机器,外部机器向外提供这类人就好。(一般用不到吧..)

  继承(我的理解—_—)

  问题:女娲要造另一批人B,这批人的模板B造好了,但是想让这批人有之前造过的那批人的特点,怎么办?先让这些人过滤一下先前的模板A,在放到B中造就ok,这样类‘B人'就继承了‘A’类人的特点。如何过滤:父实例=子原型  建B的模板,造一个a出来,这个a肯定要过滤A模板,所以让B的模板等于a就ok,问题解决。 

 //父函数,机器A,A类人。它的实例a中有[[Prototype]]属性和自定义的property属性

    function SuperType(){

    this.property=true;

    }

    //在SuperType原型对象(模具A)中添加getSuperValue方法

    SuperType.prototype.getSuperValue=function(){

    return this.property

      }

    //子函数,机器B,B类人。构造函数SubType,它的实例中有[[Prototype]]属性和自定义的subproperty属性

    function SubType(){

    this.subproperty=false;

      }

    //继承了SuperType (原型链)

    SubType.prototype=new SuperType();  //机器B=a

    //在SubType原型对象(模具B)中添加getSubValue方法

    SubType.prototype.getSubValue=function(){

return tis.subproperty;

    };  

    var insatance=new SubType();

    alert(insatance.getSuperValue()); //true

问题:引用类型值会改变,因为实例共享属性,和原型模式中的问题相同

解决方案:经典继承 (借用构造函数):其实就是把模具A设计到机器B中,但是它已经不是模板了,机器B会给生产的b们添加这些A中的属性和方法,但是可以人为控制,女娲又命令机器B根据传递不同的命令生产不同的b。

  

在子类构造函数的内部调用超类构造函数

     相当于把父类的属性实例化到子类中?Java中的super() 存在疑问

    function SuperType(){

  this.colors=['red','blue','green'];

    }

    function SubType(){

    //继承了SuperTYpe

    SuperType.call(this);

     }

    var insatance1=new SubType();

    insatance1.colors.push('black');

    alert(insatance1.colors);// 'red,blue,green,black'

    var insatance2=new SubType();

   alert(insatance2.colors);//'red,blue,green'

1传递参数:

      借用构造参数可以在子类型构造参数中向超类型构造参数传递参数

      function SuperType(name){

this.name=name;

      }

      function SubType(){

    //继承了SuperTYpe,同时还传递了参数

    SuperType.call(this,'赵云');

    //实例属性

    this.age=29;

    }

    var insatance=new SubType();

    alert(insatance.name); //赵云

    alert(insatance.age); //29

为了确保SuperType构造函数不会重写子类型的属性,可以在调用超类型构造函数之后,再添加应该在子类型中定义的属性。

问题:浪费劳动力,在机器中创建A具有的功能和属性,那么A模板就没用了,相当于回到工厂模式,都有打火机了,还要钻木取火吗....

  解决方案:组合继承   

    在公司加班没事做,现在赶着下班,故事编不下去了,后面的继承模式搬之前的记录吧..   

         原型链和构造函数技术组合到一起,使用原型链实现对原型属性和方法的继承,借用构造函数来实现对实例属性的继承。这样通过在原型上定义方法实现了函数的复用,有能够保证每个实例都有它自己的属性

    原型继承:方法可以,实例属性无法继承; 借用构造函数:实例属性可以,方法不行。 一起用,完美。

     

function SuperType(name){

   this.name=name;

   thi.colors=['red','blue','green'];

     }

    SuperType.prototype.sayName=function(){

   alert(this.name);

    };

    function SubType(name,age){

  //继承属性

  SuperType.call(this,name);

  this.age=age;

    }

     //继承方法

  SubType.prototype=new SuperType();

  SubType.prototype.sayAge=function(){

  alert(this.age);

   }

  var instance1=new SubType('zhaoyun',29);

  instance1.colors.push('black');

  alert(instance1.colors); //'red,blue,green,black'

  instance1.sayName();//zhaoyun

  instance1.sayAge();//29

  var insatance2=new SubType('诸葛瑾',25);

  alert(instance2.colrs);'red,blue,green'

  instance22.sayName();//诸葛瑾

  instance2.sayAge();//25

  下班了。。后面的翻看之前的js记录吧。。赶着回家happy!

  

JavaScript 对象的创建和对6种继承模式的理解和遐想的更多相关文章

  1. JavaScript的7种继承模式

    <JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...

  2. JavaScript对象的创建

    原文 简书原文:https://www.jianshu.com/p/6cb1e7b7e379 大纲 前言 1.简单方式创建对象的方法 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对 ...

  3. JavaScript 对象的创建和操作

    <script>         // 对象是属性的无序集合,每个属性都是一个名/值对. 属性名称是一个字符串.         // 对象种类         // 内置对象(nativ ...

  4. JavaScript对象的创建之基于构造方法+原型方式

    为了解决原型所带来的问题,此处需要通过组合构造方法和原型来实现对象的创建,将属性在构造方法中定义,将方法在原型中定义.这种有效集合了两者的优点,是目前最为常用的一种方式. function Perso ...

  5. JavaScript对象的创建之使用json格式定义

    json: javascript simple object notation. json就是js的对象,但是它省去了xml中的标签,而是通过{}来完成对象的说明. 定义对象 var person = ...

  6. javascript 对象的创建与继承模式

    针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内.写这个主要是当个笔记加总结 存在的问题请大家多多指正! 6.1理解对象 创建对象的两个方法(暂时) //第一种,通过创建一个Object ...

  7. C++ 中三种继承方式的理解

    一.公有继承(public inheritance) 1.概念:当类的继承方式为公有继承时,基类的公有成员和保护成员的访问属性在派生类中不变,而基类的私有成员不可以直接访问. 实验一下:   我们用代 ...

  8. JavaScript 对象的创建

    Object类型是JavaScript中使用最多的一种类型.创建Object实例的方式有多种,接下来一一列举. 1. Object构造函数 person1的friends属性修改影响了person2的 ...

  9. JavaScript对象的创建之基于原型方式

    原型内存模型介绍 原型是javascript中非常特殊的一个对象,当一个函数创建之后,会随之就产生一个原型对象. 当通过这个函数的构造函数创建一个具体的对象之后,在这个具体的对象中就会有一个属性指向原 ...

随机推荐

  1. Mongodb集群搭建过程及常见错误

    Replica Sets MongoDB 支持在多个机器中通过异步复制达到故障转移和实现冗余.多机器中同一时刻只 有一台是用于写操作.正是由于这个情况,为 MongoDB 提供了数据一致性的保障.担当 ...

  2. 傻瓜式操作Nagios

    傻瓜式操作Nagios   不少接触Nagios的朋友都会觉得安装配置困难,应用在企业网中所花费的时间成本很高,下面通过OSSIM来搞定它把. 为了节省资源,首先在淘汰的机器上安装一个低版本的OSSI ...

  3. oracle contains

    1. 查询住址在北京的学生SELECT student_id,student_nameFROM studentsWHERE CONTAINS( address, 'beijing' )remark: ...

  4. oracle的over函数应用(转载)

    摘自: http://www.poluoluo.com/jzxy/201004/81921.html 百度文库也记载了Oracle中over()分析函数的用法 在泡坛子的时候中无意中发现了这个函数,才 ...

  5. 1.mysql基础之 php 连接

    1.连接数据库 $db=@mysql_connect('DB_HOST','DB_USER','DB_PASS') or die("Unable to connect"); DB_ ...

  6. formValidator表单验证示例

    <script type="text/javascript">$(document).ready(function(){ $.formValidator.initCon ...

  7. 2、python,for..in语句

    for..in语句是循环语句,它迭代一个对象的序列,例如经历序列中的第一项.一个序列只是一个有序的项目的集合. for i in range(1, 5): print(i) else: print(' ...

  8. Find the largest K numbers from array (找出数组中最大的K个值)

    Recently i was doing some study on algorithms. A classic problem is to find the K largest(smallest) ...

  9. modelsim(3) - summary ,issue,tips

    1) the OEM of modelsim is 10 times slower than offical questa 2)how to the file full path in the mod ...

  10. IOS 使用KBMMW 访问JAVA 服务

    废话少说,如何使用KBMMW 做个过渡,使IOS 可以使用JAVA 的服务? 其实KBMMW 本身就要java service 的服务,但是为了把这个问题说清楚,我手工做一个例子. 首先,要使用JAV ...