①原型链式继承

 function Person(name){
this.name=name;
} Person.prototype.getName=function(){
return this.name;
} function Male(age){
this.age=age;
} Male.prototype=new Person("John"); Male.prototype.getAge=function(){
return this.age;
} var maleA=new Male(12);
console.log(maleA.getAge());//
console.log(maleA.getName());//John var maleB=new Male(25);
console.log(maleB.getAge());//
console.log(maleB.getName());//John

原型链式继承的实质是重写构造函数的原型对象,代之以一个所要继承的类型的实例。该例子中Male类型继承了Person类型。这种继承方式,所有的子类型共享父类型的属性和方法,因为原型指向的是同一个父类型实例。所以,当任一个子类型实例改变了继承来的原型属性的值,那么其他实例的原型属性的值也将被改变。为了解决这个问题,出现了借用构造函数式继承。

②借用构造函数式继承

 function Person(name){
this.name=name;
} Person.prototype.getName=function(){
return this.name;
} function Male(name,age){
Person.call(this,name);
this.age=age;
} Male.prototype.getAge=function(){
return this.age;
} var maleA=new Male("A",12);
console.log(maleA.getAge());//
console.log(maleA.name);//A
console.log(typeof maleA.getName);//undefined var maleB=new Male("B",25);
console.log(maleB.getAge());//
console.log(maleB.name);//B
console.log(typeof maleB.getName);//undefined

借用构造函数式继承的实质是在构造函数内调用父类型的构造函数,那么子类型将继承父类型构造函数内所添加的属性和方法。借用构造函数式继承的优点是可以在继承父类型的时候向父类型的构造函数传递参数,缺点是不能继承定义在父类型原型上的方法和属性。为了解决借用构造函数式继承的这个缺点,出现了组合式继承。

③组合式继承

 function Person(name){
this.name=name;
} Person.prototype.getName=function(){
return this.name;
} function Male(name,age){
Person.call(this,name);
this.age=age;
} Male.prototype=new Person(); Male.prototype.getAge=function(){
return this.age;
} var maleA=new Male("A",12);
console.log(maleA.getAge());//
console.log(maleA.name);//A
console.log(maleA.getName());//A var maleB=new Male("B",25);
console.log(maleB.getAge());//
console.log(maleB.name);//B
console.log(maleB.getName());//B

组合式继承是将原型链式继承和构造函数式继承组合在一起使用,从而发挥两者的长处。其背后的思路是使用原型链来实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能保证每个实例都有它自己的属性。

④原型式继承

 function object(o){
function F(){}
F.prototype=o;
return new F();
} var person={};
person.name='John';
person.getName=function(){
return this.name;
} var male=object(person);
male.age=22;
male.getAge=function(){
return this.age;
} console.log(male.name);//John
console.log(male.getName())//John
console.log(male.age);//
console.log(male.getAge())//

原型式继承是基于现有对象然后借助原型创建新的对象,新对象拥有现有对象的所有属性和方法,同时还不用创建自定义类型,其实质上是对现有对象的浅复制,新对象与现有对象共享现有对象的属性和方法。ECMASctipt5通过新增Object.create()方法规范了原型式继承。这个方法接受两个参数,一个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。上面的例子可以改写为:

 var person={};
person.name='John';
person.getName=function(){
return this.name;
} var male=Object.create(person,{
age:{
value:22
}
}); male.getAge=function(){
return this.age;
}
console.log(male.name);//John
console.log(male.getName())//John
console.log(male.age);//
console.log(male.getAge());//

⑤寄生式继承

 function Male(original,age){
var clone=Object.create(original);
clone.age=age;
clone.getAge=function(){
return this.age;
} return clone;
} var person={};
person.name="John";
person.getName=function(){
return this.name;
} var male=Male(person,22); console.log(male.name);//John
console.log(male.getName())//John
console.log(male.age);//
console.log(male.getAge());//

寄生式继承与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真是它做了所有工作一样的返回对象。这种继承方式新对象与现有对象共享现有对象的所有属性和方法。改变先有对象的属性的值,新对象对应属性的值也将改变。原型式继承和寄生式继承,都不能实现函数的复用。为了解决这一问题,出现了寄生组合式继承。

⑥寄生组合式继承

 function inheritPrototype(subType,superType){
var prototype=Object.create(superType.prototype);
prototype.constructor=subType;
subType.prototype=prototype;
} function Person(name){
this.name=name;
} Person.prototype.getName=function(){
return this.name;
} function Male(name,age){
Person.call(this,name);
this.age=age;
} inheritPrototype(Male,Person); Male.prototype.getAge=function(){
return this.age;
} var maleA=new Male("A",22) console.log(maleA.name);//A
console.log(maleA.getName())//A
console.log(maleA.age);//
console.log(maleA.getAge());//

寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,其背后的基本思路是:不必为了指定子类型的原型而调用父类型的构造函数,我们所需要的无非就是父类型的原型的一个副本而已。本质上,就是使用寄生式继承来继承父类型的原型,然后再将结果指定给子类型的原型。

Javascript学习笔记:6种实现继承的方式的更多相关文章

  1. JavaScript学习笔记(散)——继承、构造函数super

    构造函数中的super 今天看<JavaScript设计模式与开发实践>时,在书中看到一段代码出现super语句,第一次看到这个关键字,所以上网查了下它的作用,发现这个关键字是来自java ...

  2. javascript学习笔记(四) Number 数字类型

    数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数  toExponential() 方法 用科学 ...

  3. Java程序猿JavaScript学习笔记(2——复制和继承财产)

    计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...

  4. JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别

    JavaScript:学习笔记(7)——VAR.LET.CONST三种变量声明的区别 ES2015(ES6)带来了许多闪亮的新功能,自2017年以来,许多JavaScript开发人员已经熟悉并开始使用 ...

  5. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  6. Java程序猿的JavaScript学习笔记(3——this/call/apply)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  7. Java程序猿JavaScript学习笔记(4——关闭/getter/setter)

    计划和完成这个例子中,音符的顺序如下: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScr ...

  8. Java程序猿的JavaScript学习笔记(1——理念)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  9. Java程序猿的JavaScript学习笔记(10—— jQuery-在“类”层面扩展)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  10. Java程序猿的JavaScript学习笔记(汇总文件夹)

    最终完结了,历时半个月. 内容包含: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源代码级解析. jQuery EasyUI源代码级解析. Java程序猿的J ...

随机推荐

  1. Java虚拟机学习记录

    一.java平台无关性的基础 1.和各个平台有关的虚拟机: 2.和各个平台无关的中间语言(class文件). 二.虚拟机语言无关性的基础 1.class文件 三.java虚机机器中java程序的生命周 ...

  2. angular+ckeditor最后上传的最后一张图片不会被添加(bug)

    做法一: angularJs+ckeditor 一.页面 <textarea ckeditor required name="topicContent" ng-model=& ...

  3. Apache Spark源码走读之24 -- Sort-based Shuffle的设计与实现

    欢迎转载,转载请注明出处. 概要 Spark 1.1中对spark core的一个重大改进就是引入了sort-based shuffle处理机制,本文就该处理机制的实现进行初步的分析. Sort-ba ...

  4. ThinkPHP 3.2.3 简单后台模块开发(二)RBAC

    RBAC(Role-Based Access Controll)基于角色的访问控制 在 ThinkPHP3.2.3 中 RBAC 类位于 /ThinkPHP/Library/Org/Util/Rbac ...

  5. NEC学习 ---- 布局 -三列, 左右定宽,中间自适应

    ---恢复内容开始--- 这个布局很牛掰, 我觉得学习价值很大. 通过这个的学习, 我发现, 能将简单的事情做好, 就距离成功不远了. 其实布局就是利用所学知识, 活用. 在没看这个之前, 发现自己的 ...

  6. linux多核cpu下的负载查看

    linux下使用top命令或uptime命令 单核cpu下,负载超过0.7即意味着瓶颈,多核cpu下按核数*0.7计算负载 如2核,1.4可能即意味着负载较吃力了 查看核数 grep 'model n ...

  7. C# jquery webservices 跨域调用的问题解决方案

    前台代码: <script src="js/jquery-1.9.1.min.js" type="text/javascript"></scr ...

  8. Maven-009-Nexus 用户密码加密(安全必须)

    信息数据大爆发的时代,我们关心什么?没错,数据安全!数据安全!数据安全!(重要事情说三遍,哈哈哈...) 之前我们存放在 maven settings.xml 文件中的 Nexus 私服用户密码都是明 ...

  9. wpa supplicant 移植

    最近移植wifi,WIFI芯片使用rtl8723.在文件系统生成了设备节点.需要移植工具进行测试: iwconfig:没有密码的或者wep加密的wifi,使用iwconfig就已经够用. wpa_su ...

  10. qunit学习(一)

    QUnit是一个强大的JavaScript单元测试框架,用于调试代码.该框架是由jQuery团队的成员所开发,并且是jQuery的官方测试套件.任意正规JavaScript代码QUnit都能测试. 其 ...