①原型链式继承

 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. IOS第11天(4:UIDatePicker时间选择,和键盘处理,加载xib文件,代理模式)

    ***控制层 #import "ViewController.h" #import "CZKeyboardToolbar.h" @interface ViewC ...

  2. 【iCore3 双核心板】例程十八:USB_VCP实验——虚拟串口

    实验指导书及代码包下载: http://pan.baidu.com/s/1c1erqIc iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  3. saltstack学习

    1. 创建基础镜像 2. 创建配置文件 3. 启动容器 4. 检查创建是否成功 1. 创建基础镜像 salt-master, 文件名Dockerfile # VERSION 1.0 # TO_BUIL ...

  4. ubuntu 安装 nodejs

    http://blog.csdn.net/caib1109/article/details/51804687 我的系统环境: Ubuntu 16.04 64位 本文内容亲测可用, 请放心食用 使用淘宝 ...

  5. ASP.NET 访问路径 错误提示 HTTP 错误 404.8 原来路径中包含bin目录被拒绝

    HTTP 错误 404.8 - Not Found HTTP 错误 404.8 - Not Found 请求筛选模块被配置为拒绝包含 hiddenSegment 节的 URL 中的路径. 最可能的原因 ...

  6. Count Complete Tree Nodes || LeetCode1

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * s ...

  7. py操作mysql

    1.操作mysql的标准流程 import pymysql conn = pymysql.connect(host = "127.0.0.1", port = 3306,user ...

  8. What’s the difference between data mining and data warehousing?

    Data mining is the process of finding patterns in a given data set. These patterns can often provide ...

  9. 白话学习MVC(八)Action的执行二

    一.概述 上篇博文<白话学习MVC(七)Action的执行一>介绍了ASP.NET MVC中Action的执行的简要流程,并且对TempData的运行机制进行了详细的分析,本篇来分析上一篇 ...

  10. .net下的跨域问题

    环境: IIS7.0 MVC 4.0     公司官网 asp.net      需要的报名系统,需要有后台管理 由于是配合传统产业,所以MVC系统的数据,是由AIPS系统提供. (制作前是考虑去年用 ...