Javascript之对象的继承

继承是面向对象语言一个非常重要的部分。许多OOP语言都支持接口继承和实现继承两种方式。接口继承:继承方法签名;实现继承:继承实际的方法。在ECMAScript中函数是没有签名的,所以也就无法实现接口继承,只能支持实现继承。

在JavaScript中有大概六种继承方式,它们分别是:原型链继承,借用构造函数继承,组合继承,原型式继承,寄生式继承和寄生组合式继承。下面就是对着六种继承方式的详细介绍。

1.原型链

基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。在这里还得补充一下,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

function BasicType() {
     this.property=true;
     getBasicValue = function(){
     return this.property;
      };
}
function NewrType() {
     this.subproperty=false;
}
NewType.prototype = new BasicType();
var test = new NewType();
alert(test.getBasicValue());   //true

由上面可以知道,其本质上是重写了原型对象,代之一个新类型的实例。在通过原型链继承的情况下,要访问一个实例属性时,要经过三个步骤:1搜索实例;2搜索NewType.prototype;3搜索BasicType.prototype,此时才找到方法。如果找不到属性或者方法,者会一直向上回溯到末端才会停止。要想确定实例和原型的关系,可以使用instanceof和isPrototypeof()测试,只要是原型链中出现过的原型,都可以说是该原型链所派生实例的原型。还有一点需要注意,通过原型链实现继承时,不能使用对象字面量创建原型方法,因为这时会重写原型链,原型链会被截断。

2借用构造函数继承

其大体思路是,在子类型构造函数的内部调用超类型构造函数。

function BasicType(name) {     this.name=name;
     this.color=["red","blue","green"];
}
function NewType() {
     BasicType.call(this,"syf");     this.age=23;
}
var test = new SubType();
alert(text.name);   //syfalert(text.age);   //23

这种继承实现方式有一种优势就是,可以在子类型构造函数中向超类型构造函数中传递参数,其缺点是不能进行函数复用。

3组合式继承
      组合继承就是将原型链和借用构造函数继承模式结合起来,从而具有二者优势的方法。其理念是使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。

function BasicType(name) {
     this.name=name;
     this.colors=["red","blue","green"];
}
BasicType.prototype.sayName=function(){
     alert(this.name);
}
function NewType(name,age) {
     BasicType.call(this,name);
     this.age=age;
}
var test = new NewType("syf","23");
test.colors.push("black");
alert(text.colors);  //"red,blue,green,black"
alert(test.name);   //"syf"
alert(test.age);   //23

组合式继承避免了原型链和借用构造函数继承方式的缺陷,融合了他们的优点,成为了js中最常用的继承方式。

4原型式继承

原型链继承和原型式继承只有一字之差,但他们的机理还是有所差别的。原型式继承是借助于已有的对象来创建新对象,也就是必须有一个对象可以作为另外一个对象的基础。继承方式函数表达为:

function object (o) {
    function F(){}
    F.prototype = o;
    return new F();
}

我们可以在o的基础上进行修改,来创建特定的对象。直观上来说,其与原型链继承最大的不同之处就是没有使用new操作符。

5寄生式继承

寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来继承对象,最后再返回对象。具体为:

function createAnother ( original ){
    var clone = object (original); //通过调用函数创建一个新对象
    clone.sayHi=function(){  //以某种方式来增强这个对象
        alert("hi");
    };
    return clone; //返回对象
}

在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。使用寄生式继承来为对象添加函数,函数复用率低。

6寄生组合式继承

上面提到组合式继承,其也是JS里最常用的基础模式。但,由于其会调用两次超类型的构造函数:一次在创建字类型的时候,另一次是在子类型构造函数内部。也就是我子类型最终会包含超类型的全部实例属性,但在调用子类型构造函数时会重写这些属性。寄生组合式继承的大致思路为:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。也就是说,不必为了指定子类型的原型而调用超类型的构造函数,我们需要的是超类型原型的一个副本而已。本质上就是,使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。基本模式如下:

function inheritPrototype (subType ,superType){
      var prototype =object (superType.prototype);  //创建对象,创建超类型原型的一个副本
       prototype.constructor = subType;   //增强对象,为创建的副本添加constructor属性       subType.prototype=prototype; //指定对象,将新创建的对象赋值给子类型的原型 }

由于寄生组合式继承弥补了组合式继承缺点,所以也被众多开发者认为是最理想的继承方式。

以上就是JS里的六种继承方式的介绍,在编程实践中具体选取哪种方式还要根据当时情况来判定,适合的才是最好的,并一定非得使用组合式继承或者寄生组合式继承来完成继承。

时间: 2024-08-10 15:11:36

Javascript之对象的继承的相关文章

JavaScript的对象和继承

本文记录一种JavaScript的对象定义和继承的书写方式,也是目前使用比较普遍的一种. 1.定义对象(混合的构造函数和原型方式) // 属性在构造函数里定义 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } // 方法在原型里定义 Person.prototype.hello = function() { alert("Hello, my name is " +

JavaScript教程——对象的继承

面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承.传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承. ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅<ES6 标准入门>一书的相关章节. 原型对

Javascript之对象组合继承

感悟: 最近看了一些关于Javascript对象继承的知识,发现自己之前虽然看了一些书,但是很多知识都忘了.虽然很多东西都忘了,但再次看的过程中对这些东西不会再向刚接触时那么陌生,而且理解起来也比之前顺畅和透彻多了. 充分说明:多看书是有意义的. ————————————————————————————————————————————————————————————————————————————————————————————碎碎念 关于对象之间的继承,在Javascript中主要是通过原型对

javascript实现对象的继承的方式

在JavaScript将原型链作为实现继承的主要方法.基本原理是利用原型让一个subType引用superType的属性和方法 推荐链接 http://www.jb51.net/article/20431.htm http://zhidao.baidu.com/link?url=6gOYMdFgQlotkHu5-B7Lp-CDjd0BwfKoIcQZzNQtoW4u9UMVvRZVaEBAETt0zU_eo652JhR58CQHvQp5JbOHFa http://www.cnblogs.com/

对象(一)--对象的继承

聊一聊JavaScript中的对象的继承 吐槽 时间过得是真的快,感觉才更新博客怎么就快一个礼拜了...这两天看了点python和flask框架了解了下,最后还是打算去系统地学习下node,又看了MongoDB,之后觉得Linux挺有意思的又去找资料学习(选发行版本,装虚拟机...), 感觉把时间都折腾在这儿了,有点不务正业(想了想还是日后抽时间学习吧,现在还是把前端知识巩固好,毕竟目前是个连实习都找不到的渣渣... 不过node还是要学的,计划之后手撸一个个人博客练练手... 前言 在前一篇对

JavaScript对象 创建对象 继承

创建对象  --以下内容来自JavaScript高级程序设计 工厂模式 用函数来封装以特定接口创建对象的细节. function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; return o; } var person1 = createPerson("Nichola

Javascript对象的继承

对象的继承 Javascript主要通过原型链实现继承,原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的. 由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样.这就是Javascript继承机制的设计思想. 继承方法: (1)原型链继承方法:基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.继承是通过创建超类型的实例,并将该实例赋给子类型

JavaScript 学习笔记 - 对象和继承

本文是JavaScript The Good Part 有关对象和继承的学习笔记. 1. Object.create 本函数是ECMAScript 5中的标准函数,其作用是用一个对象作为原型来生成另一个对象,可以用以下的code 模拟实现. if(typeof Object.create !== 'function') { Object.create = function(proto){ var F = function(){}; if(typeof proto !== 'object'){ /

JavaScript大杂烩4 - 理解JavaScript对象的继承机制

面向对象之继承 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承(没有指定父类的对象,都被认为是从Object继承的). 在前面我们讨论了面向对象的封装性,在最后的地方也谈到了JavaScript的继承是通过原型和原型链实现的,下面我们就详细的展开这个问题:JavaScript到底是如何实现继承的? 继承的本质 继承的本质是重用,从语法上来讲,继承就是"D是B"的描述,其中B是基类,描述共性,D是子类,描述特性