Javascript继承机制详解


Posted in Javascript onMay 30, 2017

学完了Javascript类和对象的创建之后,现在总结一下Javascript继承机制的实现。Javascript并不像Java那样对继承机制有严格明确的定义,它的实现方式正如它的变量的使用方式那样也是十分宽松的,你可以设计自己的方法“模仿”继承机制的实现。有以下几种方法:

1、对象冒充

<script type="text/javascript">
   function classA(str){
     this.str=str;
     this.printstr=function(){
       document.write(this.str);
       document.write("<br>");
     }
     this.getstr=function(){
       return this.str;
     }    
   }
   function classB(name,str){
     //下面这两句代码相当于将classA代码体中的内容搬到这里
     this.newMethod1=classA;
     this.newMethod1(str);
     //注意,这里的写法
     delete this.newMethod1;
     //新的方法和属性的定义须在删除了newMethod之后定义,因为可能覆盖超类的属性和方法。
     this.name=name;
     this.sayName=function(){
       document.write(this.name);
       document.write("<br>");
     }
     
   }
   var a=new classB("Amy","helloworld");
   a.printstr();
   alert(a.getstr());
   a.sayName();
 </script>

function定义的代码块就相当于一个类,你可以用而且它有this关键字,你可以用this为它添加属性和方法,上述代码中有以下两句:

this.newMethod1=classA;
 this.newMethod1(str);

classB中定义了newMethod1变量,它是一个引用,指向了classA,并且还调用了classA,这两句代码的作用等同于直接将classA代码块中的内容直接复制到这里,这样创建的classB对像当然具有classA的属性和方法了。对象冒充还可以实现多继承,如下:

function ClassZ() {
 this.newMethod = ClassX;
 this.newMethod();
 delete this.newMethod;

this.newMethod = ClassY;
 this.newMethod();
 delete this.newMethod;
}

不过,classY会覆盖classX中同名的属性和方法,如果设计没问题的话,classz也不应该继承具有相同属性和方法的不同类。

2、利用call()方法

<script type="text/javascript">
   function classA(str){
     this.str=str;
     this.printstr=function(){
       document.write(this.str);
       document.write("<br>");
     }
     this.getstr=function(){
       return this.str;
     }    
   }
   function classB(name,str){
   //利用call方法实现继承
     classA.call(this,str);
     this.name=name;
     this.sayName=function(){
       document.write(this.name);
       document.write("<br>");
     }
     
   }
   var a=new classB("Amy","helloworld");
   a.printstr();
   alert(a.getstr());
   a.sayName();
 </script>

call()方法中第一个参数传递一个对象,这里的this指的是当前对象,后面的参数(可能有多个)是指传递给调用call()方法的类(函数)所需要的参数,classA.call()也是相当于直接将classA代码块中的内容直接复制到这里,classB的对象同样可以直接使用classB中的变量和方法。

3、原型链

<script type="text/javascript">
   function cA(){};
   cA.prototype.name="John";
   cA.prototype.sayName=function(){
     document.write(this.name);
     document.write("<br>");
   }
   function cB(){};
   cB.prototype=new cA();
   cB.prototype.age=23;
   cB.prototype.sayAge=function(){
     document.write(this.age);
     document.write("<br>");
   }
   var objB=new cB();
   objB.sayAge();
   objB.sayName();
   document.write("is objB the instance of cA "+(objB instanceof cA));
   document.write("<br>");
   document.write("is objB the instance of cB "+(objB instanceof cB));
   document.write("<br>");
 </script>

这里对类的定义要用prototype关键字,定义function时不带有参数,prototype后面的变量或方法相当于java中被static修饰后的属性和方法,是属于所有对象的,这里有个特殊之处:cB.prototype=new cA();该句话相当于将cA对象内容复制给cB,cB还可以追加自己的属性和方法。

4、混合方法

<script type="text/javascript">
   function cA(name){
     this.name=name;
   };
   cA.prototype.sayName=function(){
     document.write(this.name);
     document.write("<br>");
   }
   function cB(name,age){
     cA.call(this,name);
     this.age=age;
   };
   cB.prototype=new cA();
   cB.prototype.sayAge=function(){
     document.write(this.age);
     document.write("<br>");
   }
   var objB=new cB("Alan",27);
   objB.sayName();
   objB.sayAge();
   document.write("is objB the instance of cA "+(objB instanceof cA));
   document.write("<br>");
   document.write("is objB the instance of cB "+(objB instanceof cB));
   document.write("<br>");
 </script>

这里可以将属性封装在类体内,而方法利用原型方式定义,个人感觉,这是一个很好的设计方法,利用prototype定义的函数可以为多个对象重用,这里需要注意两点:cB类体内有cA.call(this,name);同时还要将cB原型赋为cB对象,即:cB.prototype=new cA();cA.call(this,name)同样相当于将cA类块内的代码复制于此,后面一句话又将cA的方法添加给cB,同时cB还可以追加自己的属性和方法。

以上是本次对Javascript继承机制的总结,不足之处望各位指正批评。

Javascript 相关文章推荐
Javascript学习笔记 delete运算符
Sep 13 Javascript
js制作的鼠标悬浮时产生的下拉框效果
Oct 27 Javascript
无限树Jquery插件zTree的常用功能特性总结
Sep 11 Javascript
node.js中watch机制详解
Nov 17 Javascript
JavaScript编写推箱子游戏
Jul 07 Javascript
JavaScript的类型、值和变量小结
Jul 09 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
Aug 11 Javascript
功能强大的jquery.validate表单验证插件
Nov 07 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
利用nvm管理多个版本的node.js与npm详解
Nov 02 Javascript
webpack打包并将文件加载到指定的位置方法
Feb 22 Javascript
JavaScript实现PC端四格密码输入框功能
Feb 19 Javascript
Vue2.x中的Render函数详解
May 30 #Javascript
jQuery实现动态删除LI的方法
May 30 #jQuery
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
May 30 #Javascript
JS给按钮添加跳转功能类似a标签
May 30 #Javascript
jQuery异步提交表单实例
May 30 #jQuery
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
May 30 #Javascript
Angularjs中使用轮播图指令swiper
May 30 #Javascript
You might like
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
2011/03/10 Javascript
由Javascript实现的页面日历
2011/11/04 Javascript
给页面渲染时间加速 干掉Dom Level 0 Event
2012/12/19 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
jquery 实现input输入什么div图层显示什么
2014/06/15 Javascript
javascript入门教程基础篇
2015/11/16 Javascript
angularjs表格ng-table使用备忘录
2016/03/09 Javascript
JS生成某个范围的随机数【四种情况详解】
2016/04/20 Javascript
JavaScript中style.left与offsetLeft的使用及区别详解
2016/06/08 Javascript
原生js实现秒表计时器功能
2017/02/16 Javascript
详解微信小程序 template添加绑定事件
2017/06/23 Javascript
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
2018/09/21 Javascript
最简单的JS实现json转csv的方法
2019/01/10 Javascript
手把手教你使用TypeScript开发Node.js应用
2019/05/06 Javascript
vue源码中的检测方法的实现
2019/09/26 Javascript
vue实现在v-html的html字符串中绑定事件
2019/10/28 Javascript
Vue extend的基本用法(实例详解)
2019/12/09 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
[59:00]OG vs TNC 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
解决pycharm 安装numpy失败的问题
2019/12/05 Python
python爬虫把url链接编码成gbk2312格式过程解析
2020/06/08 Python
怎样让char类型的东西转换成int类型
2013/12/09 面试题
护理专业的自荐信
2013/10/22 职场文书
应届毕业生求职自荐书
2014/01/03 职场文书
优秀教师自我评价范文
2014/09/27 职场文书
学生旷课检讨书500字
2014/10/28 职场文书
综合素质评价思想道德自我评价
2015/03/09 职场文书
2015年社区居委会工作总结
2015/05/18 职场文书
巴黎圣母院观后感
2015/06/10 职场文书
安全第一课观后感
2015/06/18 职场文书
退货证明模板
2015/06/23 职场文书
《比尾巴》教学反思
2016/02/24 职场文书
PyCharm配置KBEngine快速处理代码提示冲突、配置命令问题
2021/04/03 Python
Python 快速验证代理IP是否有效的方法实现
2021/07/15 Python