`
wqyang
  • 浏览: 10957 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

JavaScript中的继承机制

阅读更多
相信很多熟悉像c++,java面向对象语言的朋友们在开始接触javascript时都会有种迷失的感觉。都说javascript是基于对象而不是面向对象,那“基于”与“面向”到底有什么不同,这种机制体现在哪些方面,如何采用它所提供的机制建立面向对象的javascript。针对这些问题,本人查阅资料,整理如下,希望对大家有所帮助。(具备且仅具备基本的javascript知识即可)

1. 通过prototype属性建立面向对象的javascript

每个javascript对象都有一个内置的属性,名为prototype,用它来保存对另一个对象的引用,javascript就是利用这个引用来保存其父对象。所以,javascript通过链接机制来支持继承,这种继承结构更像是一种“has a”而不是“is a”关系。
当通过点记法引用对象的一个函数或属性时,会先从对象本身定义的函数或属性中去找,倘若没有,会从prototype所引用的对象(父对象)中寻找,如果找到则终止,倘若仍然没有找到,再从父对象的父对象中寻找,直到找到,或到达链顶仍然没有,返回undefined。
并且值得注意的是,prototype的引用可以在运行时动态更改,而不需要重新编译(基于文本,解释执行)。虽然对prototype这种继承机制褒贬不一,但其的确可以提供强大并且健壮的多态性。

下面用一个例子简单描述这种继承方式:
基类一:Vehicle
function Vehicle(){}
Vehicle.prototype.wheelCount=4;
Vehicle.prototype.capability=5;
Vehicle.prototype.refuel=function(){
    return "refuel every 300 km";
}
Vehicle.prototype.mainTasks=function(){
    return "for driving";
}

子类一:Car
function Car(){}
/*extends Vehicle*/
Car.prototype=new Vehicle();
/*overwrite below*/
Car.prototype.capability=4;
Car.prototype.refuel=function(){
    return "refuel every 200 km";
}
Car.prototype.mainTasks=function(){
    return "for driving to school, work...";
}

子类二:Bus
function Bus(){}
/*extends Vehicle*/
Bus.prototype=new Vehicle();
/*overwrite below*/
Bus.prototype.wheelCount=8;
Bus.prototype.capability=40;
Bus.prototype.mainTasks=function(){
    return "for serving citizens";
}

使用(分别调用create*生成对象并予以描述):
function describe(vehicle){
    var des="";
    des = des + "Number of wheel: " + vehicle.wheelCount;
    des = des + "\nCapability: " + vehicle.capability;
    des = des + "\nRefuel(): " + vehicle.refuel();
    des = des + "\nMainTasks(): " + vehicle.mainTasks();
    alert(des);
}
function createVehicle(){
    var vehicle = new Vehicle();
    describe(vehicle);
}
function createCar(){
    var car = new Car();
    describe(car);
}
function createBus(){
    var bus = new Bus();
    describe(bus);
}


2. 隐蔽私有属性,提高安全性

细心的您一定注意到了上面的例子已经涵盖了继承和多态,但铁杆的OO Fans一定不会放过封装,因为这涉及到数据的安全性。针对这一问题,Douglas Crockford(http://www.crockford.com)提出了一种在javascript中创建私有属性的方法,大致如下:
a. 私有属性在构造函数中使用var关键字定义;
b. 私有属性只能由特权函数(privileged function)公用访问,此类函数就是在构造函数中用this关键字定义的函数。外部客户可以通过访问特权函数访问对象的私有属性。(类似于set get方法)

下面同样用例子来描述:
基类二:Vehicle
function Vehicle(){
    var wheelCount = 4;
    var capability = 5;

    this.getWheelCount = function(){
        return wheelCount;
    }
    /*other setter and getter functions omitted*/
    ……
     this.refuel = function(){
        return "refuel every 300 km";
    }
    this.mainTasks=function(){
        return "for driving";
    }
}

注意这里的两个属性都用var关键字所修饰,它们不再是公有,访问与修改它们必须通过调用相应的公有函数完成。倘若尝试直接使用,如vehicle.wheelCount会返回undefined。

3. javascript中基于类的继承

如果你不想使用在1中介绍的基于prototype的继承方法,那么你可以采用本节介绍的,通过一个通用脚本从一个对象继承属性和函数的方式达到你的目标。这里所谓的继承其实是将“父”对象的属性和函数简单复制到“子”对象,从而创建这种继承关系。
由Netscape的Bob Clary提出的这个通用函数如下:
function createInheritance(parent, child){
    var property;
    for(property in parent){
        if(!child[property]){
            child[property] = parent[property];
        }
    }
}

上面代码清晰易懂,再配以使用代码,就不用解释了:
var child = new Child();
createInheritance(new Parent(), child);

这样便可以把父对象中有,而子对象中没有的属性和函数复制到子对象中来。

4. 结合信息隐藏与新的继承方式

这里我们结合使用信息隐藏与3中介绍的新的继承方式重写开头的例子:
基类:同2中“基类二”代码(已实现隐藏)
子类一:Car
function Car(){
    this.refuel=function(){
        return "refuel every 200 km";
    }
    this.mainTasks=function(){
        return "for driving to school, work...";
    }
}

子类二:Bus
function Bus(){
    this.mainTasks=function(){
        return "for serving citizens";
    }
}

注意这里的Car和Bus并没有wheelCount和capability属性,Bus还没有refuel函数。它们需要等待客户端代码赋予这些属性和函数,继承关系由客户端指定。

再来看客户端代码:
function createInheritance(parent, child){
    var property;
    for(property in parent){
        if(!child[property]){
            child[property] = parent[property];
        }
    }
}
function createCar(){
    var car = new Car();
    createInheritance(new Vehicle(), car);
    car.setCapability(5);
    describe(car);
}
function createBus(){
    var bus = new Bus();
    createInheritance(new Vehicle(), bus);
    car.setCapability(40);
    describe(bus);
}
funfunction describe(vehicle){
    var des="";
    des = des + "Number of wheel: " + vehicle.wheelCount;
    des = des + "\nCapability: " + vehicle.capability;
    des = des + "\nRefuel(): " + vehicle.refuel();
    des = des + "\nMainTasks(): " + vehicle.mainTasks();
    alert(des);
}

读到这里相信你已经有所体会javascript基于对象与面向对象的区别。
本文主要从Foundations of Ajax chapter5 整理而来,由于时间关系代码未经调试运行,目的只在于说明其意,还请海涵!
分享到:
评论

相关推荐

    JavaScript继承机制研究.pdf

    在本文中,我们将深入探讨JavaScript继承机制的实现方式,并对基于原型的继承、构造函数方式继承、组合继承、寄生式继承等继承机制进行了总结归纳和分析。 基于原型的继承 JavaScript是一门基于原型的语言,它不像...

    JavaScript继承机制探讨及其应用.pdf

    JavaScript继承机制探讨及其应用 JavaScript是一门弱类型语言,具有函数式编程和面向对象编程的特点。随着近几年JavaScript生态圈的发展和成熟,项目的编码量和复杂度也在呈几何级数增长。JavaScript面向对象编程中...

    浅析javascript原型继承机制

    本文将深入探讨JavaScript中的原型继承机制,帮助读者理解其中的关键概念及其工作原理。 #### 二、原型与构造函数 在JavaScript中,每个函数都有一个特殊的属性——`prototype`。当一个函数被用作构造函数时,它的...

    javascript原型继承机制参考.pdf

    javascript原型继承机制参考.pdf

    javascript原型继承机制借鉴.pdf

    javascript原型继承机制借鉴.pdf

    javascript原型继承机制归类.pdf

    javascript原型继承机制归类.pdf

    javascript原型继承机制[整理].pdf

    javascript原型继承机制[整理].pdf

    javascript继承之为什么要继承.docx

    JavaScript 中的继承机制是指子类继承父类的属性和方法,使得子类可以拥有父类的所有特征。继承是面向对象编程的基本机制之一,它可以实现代码复用、提高编程效率和增强代码的可维护性。 在 JavaScript 中,继承是...

    JavaScript继承

    与其他面向对象语言相比,JavaScript的继承机制更为复杂。在Java或C++等语言中,继承通常只需要一个关键字,如`extends`,但在JavaScript中,实现继承需要采用一系列技术。 JavaScript使用的是原型式继承,这是它与...

    JavaScript实现继承的几种方式

    在JavaScript中,面向对象编程是实现复杂功能和代码复用的关键。继承是面向对象的核心特性之一,它允许一个对象(子类)从另一个对象(父类)获取...了解这些基础概念有助于我们更好地理解和使用JavaScript的继承机制。

    Javascript 继承机制的实现

    要用ECMAScript实现继承机制,首先从基类入手。所有开发者定义的类都可作为基类。出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击。

    JavaScript学习之三 — JavaScript实现继承的7种方式

    在JavaScript中,选择合适的继承方式取决于具体需求。理解并熟练掌握这些继承方式,能让你在编写代码时更加游刃有余。文章中的`inheritance.html`和`inheritance.js`文件可能包含示例代码,帮助你直观地了解每种继承...

    深入探索JavaScript的原型继承:机制、实现与最佳实践

    在JavaScript的世界里,原型继承不仅是实现对象功能共享的核心机制,也是其面向对象编程风格的基础。本文将深入探讨JavaScript原型继承的工作原理、实现方式以及在现代Web开发中的应用。 JavaScript的原型继承是一种...

    JavaScript中的类继承

    这种继承机制使得JavaScript具有更强的表现力和灵活性,尤其在代码复用和类型安全方面。 类型安全和代码复用是类继承的主要原因。在强类型语言中,类型转换是必要的,以确保数据在不同类型的变量间正确传递。然而,...

    javascript控件开发之继承关系

    总的来说,理解并熟练掌握JavaScript的继承机制对于进行控件开发至关重要,它可以帮助我们构建出可扩展、可维护的代码结构,提升代码复用性,从而提高开发效率和应用质量。通过深入学习和实践,开发者可以创建出各种...

    JavaScript中继承原理与用法实例入门

    JavaScript中的继承机制是其面向对象特性的重要组成部分。与其他支持继承的语言不同,JavaScript并没有内置的`extend`等方法,而是依赖于构造函数和原型链的概念来实现继承。在JavaScript中,一个对象的属性和方法...

    浅析Javascript原型继承

    JavaScript中的原型继承是一种基于原型(Prototype)的继承机制,它不同于传统的类继承,而是通过对象之间的关联来实现对象间的共享属性和方法。在JavaScript中,每个函数都有一个`prototype`属性,这个属性是一个...

    理解Javascript原型继承原理

    通过以上分析,我们可以看到,在JavaScript中,通过`prototype`和`[[Prototype]]`实现了非常灵活的继承机制。这种机制允许我们轻松地扩展和重用现有对象的功能,同时也使得JavaScript成为一种非常适合面向对象编程的...

    JavaScript继承详解.doc

    JavaScript中的继承是面向对象编程的重要概念,它允许一个对象(子对象)获取另一个对象(父对象)的属性和方法,从而实现代码复用和...同时,理解JavaScript的原型、原型链和闭包等基础概念对于掌握继承机制至关重要。

Global site tag (gtag.js) - Google Analytics