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删除字符串最后一个字符
Jan 14 Javascript
js 金额格式化来回转换示例
Feb 23 Javascript
javascript实现根据身份证号读取相关信息
Dec 17 Javascript
JavaScript动态插入CSS的方法
Dec 10 Javascript
JS封装通过className获取元素的函数示例
Dec 20 Javascript
vue loadmore组件上拉加载更多功能示例代码
Jul 19 Javascript
性能优化篇之Webpack构建速度优化的建议
Apr 03 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
Apr 23 Javascript
详解vue-cli项目开发/生产环境代理实现跨域请求
Jul 23 Javascript
使用easyui从servlet传递json数据到前端页面的两种方法
Sep 05 Javascript
javascript 设计模式之享元模式原理与应用详解
Apr 08 Javascript
Vue中关闭弹窗组件时销毁并隐藏操作
Sep 01 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
为什么那些咖啡爱好者大多看不上连锁咖啡店?
2021/03/06 咖啡文化
PHP遍历数组的几种方法
2012/03/22 PHP
详解PHP的Yii框架的运行机制及其路由功能
2016/03/17 PHP
php中strlen和mb_strlen用法实例分析
2016/11/12 PHP
Laravel框架基于中间件实现禁止未登录用户访问页面功能示例
2019/01/17 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
javascript小数四舍五入多种方法实现
2012/12/23 Javascript
JS原型对象通俗&quot;唱法&quot;
2012/12/27 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
2013/04/15 Javascript
jquery控制左右箭头滚动图片列表的实例
2013/05/20 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
2015/09/14 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
javascript回到顶部特效
2016/07/30 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
2016/08/11 Javascript
JavaScript实现计数器基础方法
2017/10/10 Javascript
JS实现自定义弹窗功能
2018/08/08 Javascript
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
浅谈TypeScript的类型保护机制
2020/02/23 Javascript
在Python中使用__slots__方法的详细教程
2015/04/28 Python
python爬取亚马逊书籍信息代码分享
2017/12/09 Python
python3获取当前目录的实现方法
2019/07/29 Python
opencv导入头文件时报错#include的解决方法
2019/07/31 Python
django自带调试服务器的使用详解
2019/08/29 Python
python 实现生成均匀分布的点
2019/12/05 Python
Python 如何在字符串中插入变量
2020/08/01 Python
Python下载的11种姿势(小结)
2020/11/18 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
Giglio德国网上精品店:奢侈品服装和配件
2016/09/23 全球购物
《都江堰》教学反思
2014/02/07 职场文书
明星员工获奖感言
2014/08/14 职场文书
年终工作总结范文2014
2014/11/27 职场文书
文明上网主题班会
2015/08/14 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书
SpringCloud Alibaba 基本开发框架搭建过程
2021/06/13 Java/Android
python疲劳驾驶困倦低头检测功能的实现
2022/04/04 Python