浅谈js对象的创建和对6种继承模式的理解和遐想


Posted in Javascript onOctober 16, 2016

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对象的创建和对6种继承模式的理解和遐想全部内容了,希望大家多多支持三水点靠木~

Javascript 相关文章推荐
基于jquery的一个图片hover的插件
Apr 24 Javascript
Knockoutjs的环境搭建教程
Nov 26 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
Jan 07 Javascript
jQuery获取动态生成的元素示例
Jun 15 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
Nov 05 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 Javascript
Vue.JS入门教程之列表渲染
Dec 01 Javascript
js获取指定时间的前几秒
Apr 05 Javascript
VUE2实现事件驱动弹窗示例
Oct 21 Javascript
基于 jQuery 实现键盘事件监听控件
Apr 04 jQuery
javascript实现图片轮播代码
Jul 09 Javascript
Js逆向实现滑动验证码图片还原的示例代码
Mar 10 Javascript
利用jQuery对无序列表排序的简单方法
Oct 16 #Javascript
JS实现动态增加和删除li标签行的实例代码
Oct 16 #Javascript
js利用appendChild对标签进行排序的实现方法
Oct 16 #Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
Oct 16 #Javascript
JS实现禁止鼠标右键的功能
Oct 15 #Javascript
Vue.js快速入门实例教程
Oct 15 #Javascript
JavaScript随机生成颜色的方法
Oct 15 #Javascript
You might like
PHP里的中文变量说明
2011/07/23 PHP
Symfony2之session与cookie用法小结
2016/03/18 PHP
PHP静态成员变量
2017/02/14 PHP
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
Array 重排序方法和操作方法的简单实例
2014/01/24 Javascript
关于img的href和src取变量及赋值的方法
2014/04/28 Javascript
JavaScript生成的动态下雨背景效果实现方法
2015/02/25 Javascript
javascript下拉框选项单击事件的例子分享
2015/03/04 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
nodejs通过phantomjs实现下载网页
2015/05/04 NodeJs
JavaScript正则表达式匹配 div  style标签
2016/03/15 Javascript
nodejs微信公众号支付开发
2016/09/19 NodeJs
微信小程序开发之录音机 音频播放 动画实例 (真机可用)
2016/12/08 Javascript
vue父子组件的数据传递示例
2017/03/07 Javascript
vue.js之vue-cli脚手架的搭建详解
2017/05/05 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
JavaScript实现一个空中避难的小游戏
2017/06/06 Javascript
vue之浏览器存储方法封装实例
2018/03/15 Javascript
当vue路由变化时,改变导航栏的样式方法
2018/08/22 Javascript
[48:47]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python编程之微信推送模板消息功能示例
2017/08/21 Python
Python+OpenCV让电脑帮你玩微信跳一跳
2018/01/04 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
Python数据结构之图的应用示例
2018/05/11 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
Python打印特殊符号及对应编码解析
2020/05/07 Python
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2015/09/07 面试题
历史专业毕业生的自我鉴定
2013/11/15 职场文书
2014年应届大学生自我评价
2014/01/09 职场文书
选秀节目策划方案
2014/06/06 职场文书
群众路线教育实践活动学习心得体会
2014/10/30 职场文书
语文复习计划
2015/01/19 职场文书
军事理论课感想
2015/08/11 职场文书
励志语录:你若不勇敢,谁替你坚强
2019/11/08 职场文书
python实现图片批量压缩
2021/04/24 Python
HTML中的表单元素介绍
2022/02/28 HTML / CSS