浅谈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 相关文章推荐
用JavaScript 处理 URL 的两个函数代码
Aug 13 Javascript
javascript textarea光标定位方法(兼容IE和FF)
Mar 12 Javascript
使用Jquery实现点击文字后变成文本框且可修改
Sep 21 Javascript
JS方法调用括号的问题探讨
Jan 24 Javascript
jquery复选框checkbox实现删除前判断
Apr 20 Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
Jul 17 Javascript
Windows安装Node.js报错:2503、2502的解决方法
Oct 25 Javascript
关于微信小程序登录的那些事
Jan 08 Javascript
layUI实现前端分页和后端分页
Jul 27 Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 Javascript
通过vue刷新左侧菜单栏操作
Aug 06 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
几种显示数据的方法的比较
2006/10/09 PHP
加速XP搜索功能堪比vista
2007/03/22 PHP
php 引用(&)详解
2009/11/20 PHP
解析php类的注册与自动加载
2013/07/05 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
总结PHP代码规范、流程规范、git规范
2018/06/18 PHP
php微信公众号开发之校园图书馆
2018/10/20 PHP
javascript 中String.match()与RegExp.exec()的区别说明
2013/01/10 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
jquery(hide方法)隐藏指定元素实例
2013/11/11 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
jquery跟js初始化加载的多种方法及区别介绍
2014/04/02 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
jquery实现列表上下移动功能
2016/02/25 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
JS传值出现中文参数乱码的解决方法
2016/06/30 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
微信小程序自定义tab实现多层tab嵌套功能
2018/06/15 Javascript
express中static中间件的具体使用方法
2019/10/17 Javascript
[53:50]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
zbar解码二维码和条形码示例
2014/02/07 Python
python实现大转盘抽奖效果
2019/01/22 Python
Python 列表去重去除空字符的例子
2019/07/20 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
python连接mysql有哪些方法
2020/06/24 Python
python使用opencv resize图像不进行插值的操作
2020/07/05 Python
如何在VSCode下使用Jupyter的教程详解
2020/07/13 Python
CSS3基础(RGBa、text-shadow、box-shadow、border-radius)
2012/11/13 HTML / CSS
车间组长岗位职责
2013/12/20 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
工伤调解协议书
2016/03/21 职场文书
工作报告范文
2019/06/20 职场文书
Python opencv缺陷检测的实现及问题解决
2021/04/24 Python