①原型链式继承

 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. Android中<meta-data>的使用

    [转]  原文 在AndroidManifest.xml中,<meta-data>元素可以作为子元素,被包含在<activity>.<application> .& ...

  2. ListView或GridView的Adapter使用Glide加载图片异常

    报错信息为:You must not call setTag() on a view Glide is targeting 原因就是View使用setTag后导致Glide之前请求的标记被清除,强制转 ...

  3. 录制简单的自动化测试工具SlikMobile初体验

    今天朋友推荐了款自动化测试工具SlikMobile,下载了个试用了下,感觉还是很容易入门和上手的,感觉和testin的工具差不多,跨平台,多语言支持,支持图片.文本和Native Class三种对象方 ...

  4. struts2:数据校验,通过XWork校验框架实现(validation.xml)

    根据输入校验的处理场所的不同,可以将输入校验分为客户端校验和服务器端校验两种.服务器端验证目前有两种方式: 第一种: 参考:struts2:数据校验,通过Action中的validate()方法实现校 ...

  5. Java提高篇——Java实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  6. Invoke() 方法是 Unity3D 的一种委托机制

    Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("SendMsg", 5);   它的意思是:5 秒之后调用 SendMsg() 方法: 使用 Inv ...

  7. Web前端开发规范文档

    Web前端开发规范文档 规范目的: 使开发流程更加规范化. 通用规范: TAB键用两个空格代替(windos下tab键占四个空格,linux下TAB键占八个空格). CSS样式属性或者JAVASCRI ...

  8. adadmin: error while loading shared libraries: libclntsh.so.10.1

    EBS R12.2运行adadmin报错: $ adadmin adadmin: error while loading shared libraries: libclntsh.so.10.1: ca ...

  9. [Ahoi2013]差异

    后缀数组+单调栈 代码 #include<cstdio> #include<algorithm> #include<cstring> using namespace ...

  10. iOS 杂记

    一,demo 1,视图跳转 MaryPopin:  https://github.com/Backelite/MaryPopin 2,Nimbus是一个开源的iOS框架,比起Three20,Nimbu ...