JavaScript基础之继承.doc_第1页
JavaScript基础之继承.doc_第2页
JavaScript基础之继承.doc_第3页
JavaScript基础之继承.doc_第4页
JavaScript基础之继承.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaScript基础之继承 前些天写了一篇关于JavaScript基础的帖子JavaScript基础之对象。在那篇帖子中说马上就会写一些关于继承方面的东西。可是上周杂事太多,都没有时间动笔,就一直拖到今天才终于下笔写了。上一篇帖子中很多人认为我自己的东西太少了,所以这篇帖子中在说完基础知识之后我会给出一个完整的例子。 大家都知道面向对象语言的三大特性为:封装、继承、多态。面向对象的语言之所以强大就全依赖于这三大特性。脚本作为一种准面向对象的语言虽然有先天的不足,但还是能在某种程度上去实现这些特性。实现最多、技术最成熟的就数继承了,不过脚本也不能像C#一样简单地用一个:就能实现继承,而是要自己去实现继承的细节。1 继承的几种实现方法 要实现继承首先就必须要有子类、父类(超类、基类等叫法)。子类去继承父类的方法和属性。在脚本里所有开发人员定义的类都可以作为父类,不过本地类(native object)和宿主类(host object)不能作为父类。由于脚本里面没有访问修饰符,父类所有的属性和方法都可以被子类直接访问。子类也可以扩展父类的属性和方法。1.1 call()方法 Call方法是脚本的一个内置(build in)方法。官方说明为:调用一个对象的方法,以另一个对象替换当前对象。语法为:call(thisObj,arg1, arg2, ,.argN)。用这个方法可以很容易地模拟继承的实现: 类(funCreateElement)有一个属性(sAClassName)和一个方法(createALink)。它的作用是创建一个DOM元素。这个类使用this关键字给属性赋值,这样就确保了所有的实例指向的都是自己的值。 1function funCreateElement(sClassName) 2 3 this.sAClassName=sClassName; 4 5 this.createALink=function() 6 7 var oA=document.createElement(a); 8 oA.className=this.sAClassName; 9 return oA;10 11 1function funCurrNavi()2 3 / 继承元素创建类4 funCreateElement.call(this,tblNavigatorA);5 这样就实现了一个最简单的继承了。在funCurrNavi的实例里就可以直接使用funCreateElement类里面的方法了。 var o=new funCurrNavi(); o.createALink(); 1.2 apply()方法 apply方法也是脚本的一个内置(build in)方法。其用法和call对象类似。官方说明为:应用某一对象的一个方法,用另一个对象替换当前对象。语法为:apply(thisObj,argArray)。实际上这两个的作用几乎是相同的,要注意的地方是call(thisObj,arg1, arg2,)中的arg参数可以是变量,而apply(thisObj,argArray)中的参数为数组集合。由于和call方法就只有参数的不同而已所以就不举例子了。1.3 原型链 Prototype对象是所有类的源头。如果修改了prototype类的方法则这个修改会反映到所有类的实例里面。比如:在totype里面加一个方法trim(),Stotype.trim=function()。那么所有的字符串都会具有trim()方法了(aa.trim()。由于prototype的这个特性,我们就可以实现继承方法了。如果用原型链的方式重定义前面的例子,它们将变为下面的形式: 这种方式采用funCurrNtotype=new funCreateElement()方法,将funCreateElement类里面所有的属性和方法都复制到funCurrNavi类里面。非常的快捷。这种方式虽然非常的快捷,但是也有其缺点。采用这种方式时子类所有的属性和方法都必须在funCurrNtotype=new funCreateElement()语句之后。因为该语句会覆盖funCurrNavi类原有的prototype类,添加了新的属性和方法的原有prototype类将被销毁。而且父类和子类都没有参数,只能通过设置属性的方法传入参数。 1function funCreateElement() 2 3 4 5 funCreateEtotype.sAClassName=sClassName; / 样式类 6 funCreateEtotype.createALink=function() 7 8 var oA=document.createElement(a); 9 oA.className=this.sAClassName;10 return oA;11 12 13 14 function funCurrNavi()15 16 17 18 funCurrNtotype=new funCreateElement();19 funCurrNtotype.showMeInDiv=function()20 21 1.4 混合方式 混合方式就是指将前两种方式结合起来使用,取长避短。在call方式里面定义类的方式不理想,相同的方法在实例里面被重复的实例化了。原型链的方法则因为没有参数而不理想,使用参数前得额外的去设置其属性,不如构造函数的参数来的方便。根据上一篇帖子中定义类的混合方式,我们重新定义funCreateElement类: 1function funCreateElement(sClassName) 2 3 this.sAClassName=sClassName; 4 5 6 funCreateEtotype.createALink=function() 7 8 var oA=document.createElement(a); 9 oA.className=this.sAClassName;10 return oA;11 然后在funCurrNavi类里面采用call方式继承funCreateElement类的属性,采用原型链的方式继承其方法。如下: 1function funCurrNavi(sLinkText) 2 3 funCreateElement.call(this,tblNavigatorA); 4 5 this.LinkText=sLinkText; 6 7 8 funCurrNtotype=new funCreateElement(); / 继承超链接类 9 10 funCurrNtotype.showMeInDiv=function()11 12 var oLink=this.createALink();13 oLink.text=this.LinkText;14 采用funCreateElement.call(this,tblNavigatorA)方式继承其参数,funCurrNtotype=new funCreateElement()方式继承其方法。从而达到方法不会被实例化多次的目的。2 实例 前面讲述了几种继承的实现方式,这一小节就利用前面讲述的方法去练习一个小例子。这个例子是根据一个字符串去呈现一个树状的列表,这种需求常见于页面的导航中。由于只是为了辅助讲述继承,例子有些地方不免有些牵强附会和小题大做的地方。这些就希望各位网友包涵了,请各位珍惜自己的砖头了。我在这里戴上钢盔等候大家的批评了。:) 下面是其运行成功的样图: 左面的那个是用table作为容器,右边的那个是用div作为容器。 1 2 3 Create Admin Pages Navigator 4 5 /*导航table的样式*/.tblNavigator 6 7 border: 2px solid #FFD7AC; 8 width: 200px; 9 margin: 3px; 10 background: #fff; 11 margin-top: 5px; 12 margin-bottom: 5px; 13 border-collapse: collapse; 14 15 /*每个根节点的样式*/.tblNavigatorRoot 16 17 height: 30px; 18 line-height: 30px; 19 text-align: left; 20 vertical-align: middle; 21 22 /*根节点的子节点的样式*/.tblNavigatorTD 23 24 border-collapse: collapse; 25 border: 1px solid #FFE6CB; 26 height: 22px; 27 text-indent: 15px; 28 background: #fff; 29 width: 100%; 30 31 /*导航中的超链接*/.tblNavigatorA 32 33 font-weight: 700; 34 text-decoration: none; 35 color: Black; 36 width: 100px; 37 38 39 40 41 42 43 44 45 46 47 48 var sNavigatorMain = 49 50 sNavigators: 51 52 root:name:root1, 53 sons:name:root1Son1,url:bcc,name:root1Son2,url:bcc 54 , 55 56 root:name:root2, 57 sons:name:root2Son1,url:bcc 58 , 59 60 root:name:root3, 61 sons:name:root3Son1,url:bcc,name:root3Son2,url:bcc,name:root3Son3,url:bcc 62 , 63 64 root:name:root4, 65 sons:name:root4Son1,url:bcc,name:root4Son3,url:bcc 66 67 , 68 69 root:name:root4, 70 sons:name:root4Son1,url:bcc,name:root4Son3,url:bcc 71 72 73 ; 74 75 /* 76 * 创建一个元素 77 * sClassName:元素的样式控制类 78 */ 79 function funCreateElement(sClassName) 80 81 / 样式类 82 this.sAClassName=sClassName; 83 84 85 /* 86 * 创建超链接元素 87 * sText:超链接显示的文本 88 * sUrl:超链接的href 89 * sTarget:打开链接的目标 90 * 返回:超链接元素 91 */ 92 funCreateEtotype.createALink=function(sText,sUrl,sTarget) 93 94 var oA=document.createElement(a); 95 oA.href=sUrl; / 链接文本 96 oA.className=this.sAClassName; / 样式类 97 oA.target=sTarget; / 打开链接的目标 98 oA.appendChild(document.createTextNode(sText); / 显示文本 99 100 return oA;101 102 103 /*104 * 创建Div元素105 * sText:显示的文本106 * 返回:Div元素107 */108 funCreateEtotype.createDivBlank=function()109 110 var oDiv=document.createElement(div);111 oDiv.className=this.sAClassName;112 return oDiv;113 114 115 /*116 * 创建Div元素117 * sText:显示的文本118 * 返回:Div元素119 */120 funCreateEtotype.createDivNoLink=function(sText)121 122 var oDiv=document.createElement(div);123 oDiv.className=this.sAClassName;124 oDiv.appendChild(document.createTextNode(sText);125 126 return oDiv;127 128 129 /* 130 * 创建一个模块的节点131 * oNaviJSON:一个模块节点的文本132 * oParentObject:父节点133 * sClassNameRoot:根节点的样式类134 * sClassNameNode:子节点的样式类135 */136 function funCurrNavi(oNaviJSON,oParentObject,sClassNameRoot,sClassNameNode)137 138 / 继承元素创建类139 funCreateElement.call(this,tblNavigatorA);140 141 / 当前导航的菜单142 this.oNavi=oNaviJSON;143 / 当前导航的父节点144 this.oParent=oParentObject;145 / 根节点的样式类146 this.oNClassNameRoot=sClassNameRoot;147 / 子节点的样式类148 this.oNClassNameNode=sClassNameNode;149 150 151 / 继承超链接类152 funCurrNtotype=new funCreateElement();153 154 / 显示自己(在Table容器里)155 funCurrNtotype.showMeInTable=function()156 157 / 在父容器中添加一行,并将父节点写入158 this.oParent.insertRow(0);159 this.oParent.rows0.onclick=function()alert(this.innerText);160 this.oParent.rows0.insertCell(0);161 this.oParent.rows0.cells0.className=this.oNClassName;162 this.oParent.rows0.cells0.appendChild(document.createTextNode(this.oN);163 164 var j=this.oNavi.sons.length;165 for(var i=0;ij;i+)166 167 this.oParent.insertRow(i+1);168 this.oParent.rowsi+1.insertCell(0);169 this.oParent.rowsi+1.cells0.className=this.oNClassNameNode;170 this.oParent.rowsi+1.cells0.appendChild(this.createALink(this.oN,this.oNavi.sonsi.url,_blank);171 172 173 174 / 显示自己(在Div容器里) 返回:div175 funCurrNtotype.showMeInDiv=function()176 177 / 创建一个暂时的容器178 var oDivContainer=document.createElement(div);179 180 / 在父容器中将父节点写入181 var oDivRoot=this.createDivNoLink(this.oN);182 oDivRoot.className=this.oNClassNameRoot;183 oDivRoot.onclick=function()alert(this.innerText);184 oDivContainer.appendChild(oDivRoot);185 186 / 链接节点187 var oDivLinkNode;188 189 var j=this.oNavi.sons.length;190 for(var i=0;i=0;i-)229 230 CNavi=new funCurrNavi(this.oNavis.sNavigatorsi,oTBody,tblNavigatorRoot,tblNavigatorTD);231 CNavi.showMeInTable();232 233 234 return oTable;235 236 237 / 创建所有的节点(以Div为容器)238 funCurrNtotype.createNavigatorsInDiv=function()239 240 / 创建容器241 var oContainer=document.createDocumentFragment();242 243 var j=this.oNavis.sNavigators.length;244 var CNavi;245 246 for(var i=0;ij;i+)247 248 CNavi=new funCurrNavi(this.oNavis.sNavigatorsi,tblNavigatorRoot,tblNavigatorTD);249 oContainer.appendChild(CNavi.showMeInDiv();250 251 252 return oContainer;253 254 255 /*256 * 供调用的函数257 * sNavigatorMain:所有节点的文本258 * sParentID:导航父容器的ID259 */260 function showNavigator(sNavigatorMain,sParentID,sFlag)261 262 var oTemp=eval(ddkk=+sNavigatorMain);263 var main=new funCurrNavis(oTemp,tblNavigator);264 265 if(sFlag=div)266 267 document.getElementById(sParentID).appendChild(main.createNavigatorsInDiv();268 269 else270 271 document.getElementById(sParentID).appendChild(main.createNavigatorsInTable();272 273 274 275 276277 278 / showNavigator(sNavigators:root:name:用户管理,sons:name:个人信息管理,url:/UserMng/frmMyInfoMng.aspx,name:本单位用户管理,url:/UserMng/frmUserMng.aspx,name:本单位信息管理,url:/SysMaintenance/frmDeptInfo.aspx,root:name:申报管理,sons:name:项目管理,url:/Declaration/frmProjAppMng.aspx,root:name:留言板管理,sons:name:给管理员留言,url:/Information/frmQuestion.aspx,divMain,table);279 280 /showNavigator(sNavigators:root:name:用户管理,sons:name:个人信息管理,url:/UserMng/frmMyInfoMng.aspx,name:本单位用户管理,url:/UserMng/frmUserM.aspx,name:本单位信息管理,url:/SysMaintenance/frmDeptInfo.aspx,root:name:申报管理,sons:name:项目管理,url:/Declaration/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论