javascript中实现继承的三种方式:原型继承、借用构造函数继承、混合继承:

 /*
js当中的继承 js中 构造函数 原型对象 实力对象的关系:
1 构造函数.prototype = 原型对象
2 原型对象.constructor = 构造函数(模板)
3 原型对象.isPrototypeOf(实例对象) 判断实例对象的原型是不是当前对象
4 构造函数 实力对象 是 类和对象的关系
*/ /*
1 原型继承
给子类构造函数的原型对象赋值为父类构造函数的实例
赋值之后产生的关系:
1 子类的原型对象是父类的一个实例 Son.prototype 是 new Father()
2 父类的方法和属性,子类可以在原型中得到
3 子类的原型对象的构造器是父类模板 Son.prototype.constructor 是 Father
4 子类的原型对象的原型对象是父类的原型对象 Son.prototype.prototype 是Father.prototype
原型继承的特点:
子类继承了父类所有属性方法发和 父类原型对象中的属性和方法
缺点: 不能在子类实例化对象的时候给父类的属性赋值,继承父类的值和子类对象实例化分开了。
*/ //父类构造函数
function Father(name){
this.name = name;
}
//父类原型对象
Father.prototype={
constructor: Father,
id:10,
sayName:function(){
alert(this.name);
}
}; //子类构造函数
function Son(age){
this.age = age;
}
//子类原型对象 这一家子都姓张
Son.prototype = new Father("张"); //子类的实例 能够使用父类的属性和方法
var s1 = new Son(18);
//s1.sayName(); //张
//alert(s1.age); //18 /*
原型继承的特点:
子类继承了父类所有属性方法发和 父类原型对象中的属性和方法
缺点: 不能在子类实例化对象的时候给父类的属性赋值,继承父类的值和子类对象实例化分开了。
*/ /*
2 类继承(借用构造函数) 只继承父类的构造函数,父类的原型对象没有继承过来
利用call 或者apply进行函数绑定,借用父类构造函数的属性和方法
*/
//父类构造函数
function Father(name){
this.name = name;
}
//父类原型对象 在子类中不能继承父类原型对象中的内容
Father.prototype.id = 10; //子类构造函数
function Son(name,age){
//name属性是父类的 不是子类的 借用父类的构造函数 把属性绑定给子类的实例对象
Father.call(this,name);
this.age = age;
}
//实例化子类对象 在这里可以直接给继承来的属性赋值
var s2 = new Son("z3",18);
//alert(s2.name); //z3 父类构造函数绑定来的属性
//alert(s2.age); //18 子类自己的属性 /*
类继承(借用构造函数) 的特点:
优点: 能够在实例化子类对象时候给继承父类的属性赋值
缺点:父类的原型对象中的内容无法继承
*/ /*
3 混合继承:原型继承 和 借用构造函数继承 的混合
特点:
优点:1 能够在实例化子类对象的时候给继承来的属性赋值
2 能够继承父类的原型对象中的方法
缺点: 继承了两次父类的模版,分别是call绑定和子类原型对象赋值的时候
如果继承来的属性特别多,这会很耗费时间来维护
*/
//父类
function Father(name){
this.name = name;
}
//父类的原型对象
Father.prototype = {
constructor:Father,
id:10,
sayName:function(){
alert(this.name);
}
};
//子类
function Son(name,age){
//借用父类构造函数 绑定子类方法 为子类继承来的属性赋值
Father.call(this,name);
this.age = age;
}
//原型继承 不传递参数,继承自父类的属性赋值交给借用父类构造函数去做
Son.prototype = new Father(); //使用子类实例化对象
var s3 = new Son("l4",20);
//alert(s3.name); //父类属性
//alert(s3.id); //父类原型对象的属性
//alert(s3.age); //自己的属性
//s3.sayName(); //父类原型对象中的方法
/*
混合集成的特点:
优点:1 能够在实例化子类对象的时候给继承来的属性赋值
2 能够继承父类的原型对象中的方法
缺点: 继承了两次父类的模版,分别是call绑定和子类原型对象赋值的时候
如果继承来的属性特别多,这会很耗费时间来维护
*/

但是 上面三种方式 即使是混合继承也有弊端,下面用js模拟一下extends的继承方,来实现不会重复继承父类的构造函数:

 /*
javascript模拟extends方法,
目的:
1子类实例化能够赋值继承来的属性
2 继承父类的原型对象
3 父类的构造函数只继承一次
*/ //1 我们模拟一个extends函数 用于实现类之间的继承 传入父类和子类
function extend(son,father){
//让子类继承父类的原型而不继承父类构造函数的内容
var f = new Function(); //临时空函数,目的是函数内部是空的 但是原型是父类的原型
f.prototype = father.prototype; //让空函数的原型指向父类的原型
son.prototype = new f(); //让子类的原型指向一个空函数,空函数的原型是父类的原型,这就避免了父类构造函数的属性被重复实现
//给子类添加一个superClass属性保存父类的原型对象,防止自己重写了父类方法后 无法调用父类原型对象中的方法
son.superClass = father.prototype;
//为父类原型对象添加构造器 如果父类原型对象忘记加构造器这里给他加上
if(father.prototype.constructor == Object.prototype.constructor){
father.prototype.constructor = father;
}
}
//2 父类
function Father(name){
this.name = name;
}
//父类的原型对象
Father.prototype = {
constructor: Father,
sayName:function(){
alert(this.name);
}
}; //3 子类
function Son(name,age){
//借用构造函数:为子类绑定父类的构造函数中属性
// Father.call(this , name); 这里不这样写,为了解耦,增加通用性,经过extentds函数之后,子类里面有了父类的属性
Son.superClass.constructor.call(this , name); //Son.superClass是父类的原型对象,consturctor就是父类构造函数
this.age = age;
}
//原型继承
//Son.prototype = new Father(); //会再次绑定一次父类的构造函数 ,这里为了不重复继承父类构造函数,只继承父类原型对象 我们用自己
//调用自己的继承方法 实现为子类继承父类的原型对象 而不继承父类的构造函数 extend(Son,Father); //使用子类
var s4 = new Son("haha",33);
alert(s4.name); //haha 父类继承来的属性
alert(s4.age); //33 自己的属性
s4.sayName(); //haha 父类继承来的方法
//重写父类方法
s4.sayName = function(){
alert("hello i am son");
};
s4.sayName(); //hello i am son 重写方法覆盖了父类的sayName
//重写之后还想调用父类的方法 需要绑定一下 指定是我这个对象来调用
Son.superClass.sayName.call(s4); //haha

javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承的更多相关文章

  1. JavaScript 创建对象的七种方式

    转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以 ...

  2. JavaScript创建对象的几种 方式

    //JavaScript创建对象的七种方式 //https://xxxgitone.github.io/2017/06/10/JavaScript%E5%88%9B%E5%BB%BA%E5%AF%B9 ...

  3. JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)

    JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...

  4. JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习

    虽然经常说是做前端开发的,但常常使用的技术反而是JQuery比较多一点.在JavaScript的使用上相对而言少些.尤其是在创建对象使用原型链继承上面,在项目开发中很少用到.所以今天做个demo练习一 ...

  5. [转载]javascript创建对象的几种方式

    原文链接:http://qingfeng825.iteye.com/blog/1935648 1. 工厂方法:能创建并返回特定类型对象的工厂函数(factory function). function ...

  6. JavaScript事件处理的三种方式(转)

    一.什么是JavaScript事件? 事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 事件可能是用 ...

  7. Flex(ActionScript)与JavaScript交互的两种方式示例

    随着各单位部门信息化进程的不断发展,互通互联.共享协调不断的被越来越多的客户所重视.很多新项目都要去必须能够集成已有的早期系统,至少也要能够实现交互对接.今天跟大家分享的是系统对接中ActionScr ...

  8. 原生javascript实现异步的7种方式

    1.$(document).ready 点评: 需要引用jquery :兼容所有浏览器. 2.标签的async=”async”属性 async的定义和用法(是HTML5的属性) async 属性规定一 ...

  9. JavaScript声明全局变量三种方式的异同

    JavaScript中声明变量很简单var(关键字)+变量名(标识符). 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这 ...

随机推荐

  1. WordPress源代码压缩优化及常见问题的解决

    先来看看效果: 意思就是让你的源代码看起来都挤在一起,这样如果别人想看你的源代码的话就不容易看懂了,(当然如果别人实在想看的话也可以通过某些软件的整理代码的功能来实现,比如IDEA的Ctrl+alt+ ...

  2. Eclipse CDT开发环境搭建及问题记录(Windows)

    这两天在整Eclipse,在此记录过程中遇到的一些问题. 1.安装JDK,配置系统路径: 2.下载Eclipse 直接访问Eclipse官网(https://www.eclipse.org/downl ...

  3. protobuf lib库的使用

    问题记录: 1.在使用protobuf反射机制动态加载解析proto文件时,发现当proto文件中含有import系统proto文件的语句时,无法解析文件,解决方法是添加路径映射. google::p ...

  4. JAVA基本数据类型和引用数据类型的区别

    [基本数据类型] 基本数据类型:声明时直接在栈内存中开辟空间,并直接在当前内存中存放数据,赋值时传递的是变量中的值,总的来说,基本数据类型是传值的. [引用数据类型] 声明引用数据类型(数组或对象), ...

  5. Redis的安装和部署

    基本知识 1.Redis的数据类型: 字符串.列表(lists).集合(sets).有序集合(sorts sets).哈希表(hashs) 2.Redis和memcache相比的独特之处: (1)re ...

  6. [poj2185]Milking Grid_KMP

    Milking Grid poj-2185 题目大意:给出一个字符矩阵,求最小覆盖矩阵(可以残余). 注释:$1\le R\le 10^5$,$1\le C \le 75$ 想法:和bzoj1355不 ...

  7. C语言程序设计第三次作业--选择结构(1)

    Deadline: 2017-10-29 22:00 一.学习要点 掌握关系运算符和关系表达式 掌握如何判断两个实数相等 掌握常用数学函数的使用 掌握逻辑运算符和逻辑表达式 理解逻辑运算的短路特性 掌 ...

  8. Alpha冲刺Day7

    Alpha冲刺Day7 一:站立式会议 今日安排: 由林静和周静平共同完成企业风险分级展示这一模块的分级列表展示,该模块主要提供企业自查风险的条件查询功能 由黄腾飞和张梨贤共同完成企业风险分级展示的分 ...

  9. 学号:201621123032 《Java程序设计》第10周学习总结

    1:本周学习总结 1.1.:以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2:书面作业 2.1.:常用异常--结合题集题目7-1回答 2.1.1:自己以前编写的代码中经常出现什么异常.需要捕 ...

  10. Linux下ip配置与网络重启

    ip配置 //以下ip配置重启失效 sudo ifconfig 192.168.1.1 sudo ifconfig 192.168.1.1 netmask 255.255.255.0 网络重启 //关 ...