①原型链式继承

 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. 解决JQuery EasyUI onLoadSuccess执行两次的问题

    今天使用EasyUI的datagrid时发现首次打开页面时onLoadSuccess方法执行了两次.后来发现主要问题是datagrid被初始化了两次.主要原因是一开始html中声明了dg为easyui ...

  2. DS Tree 已知先序、中序 => 建树 => 求后序

    参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...

  3. MessageBox Class

    Examples http://msdn.microsoft.com/en-us/library/aa969773(v=vs.110).aspx Displays a message box that ...

  4. Mac OS X系统下利用VirtualBox安装和配置Windows XP虚拟机

    准备工作 下载并安装VirtualBox for Mac到https://www.virtualbox.org/wiki/Downloads下载VirtualBox <版本> for OS ...

  5. [daily] 宇宙终极shell之zsh

    序 很久以前,我就知道zsh.后来在并不遥远的好几年前,第一次装arch的时候,默认shell就是zsh.虽然用起来不太习惯,但是仍然蛮好用的. 决定好好的学一下zsh,如果可以就切换过去,毕竟bas ...

  6. 存储过程:当基站ID大于1000的时候,把ID通过存储过程插入表,然后处理

    不推荐这么弄,没办法,项目逼到这了,以后尽量避免这样的需求发生! CREATE OR REPLACE PROCEDURE insert_tempStation_proc(v_instr in clob ...

  7. 【Apache】apache简单配置URL重写规则

    [概述]URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程.举个例子来说,如果通过浏览器进来的URL是index.php?type=news&& ...

  8. Java基础之扩展GUI——高亮元素、上下文菜单、移动旋转元素、自定义颜色(Sketcher 10)

    窗口应用程序. 本例在上一版的基础上实现了高亮元素.移动元素.上下文菜单.旋转元素.设置自定义颜色. 1.自定义常量包: // Defines application wide constants p ...

  9. 2016/12summary

    应用服务器处理业务逻辑,web服务器处理html文件.web服务器更加简单.应用服务器有tomcat,jboss,weblogic,web服务器有IIS,Apache. 徐总:core里面做业务逻辑, ...

  10. PHP的serialize序列化数据与JSON格式化数据

    serialize序列化 我们在一些老的WEB系统中可能会看到在数据库或在文本文件中存储着一大串貌似有着特殊含义的字符串文本内容.我们仔细看会发现它具有数据类型和结构等信息,但是它并不容易人工阅读,它 ...