zoukankan      html  css  js  c++  java
  • [译作]Class in Jscript Part I

    【原文地址】 Classes in Jscript - Part I

    【原文发表日期】 Monday, September 24, 2007 9:23 AM by don.raman

    我是Ritesh Parikh,最近刚转入Jscript Team作一名SDET(译注:我也不知道SDET是什么样的岗位:()。我刚接触Jscript时,我有很多的疑问。其中一个就是 Jscript是否支持面向对象?(译注:这里的Jscript是MS所实现的Javascript,由于MS的Jscript完全兼容于Javascript 1.5,并在此基础上,针对IE做了一些扩展。这个系列里,介绍的内容实际上是Javascript 1.5中对面向对象支持。因此这些内容适合于我们目前广泛意义上的Javascript)

    通常情况下,一种语言要支持面向对象的能力,必须具备以下的能力:

    l 一种将相关函数组织在一个模块中,并封装他们实现细节的机制。比如:类。

    l 一种重用函数,广泛意义上的继承机制。

    l 一种逻辑上做相同事情,但却有不同实现的机制。我们通常称之为多态机制。

    JScript支持以上所有的机制。在这篇博客中,我将会介绍Jscript是如何支持定义一个类的。

    Jscript并不支持一般意义上的“类”,这就决定了它与传统上的面向对象语言,如C++或者JAVA有很大的不同。Jscript不支持传统意义上的类继承,取而代之的是一种利用prototype技术来实现(模拟)类的继承。

    如果Jscript不支持一般意义上的类,那它是如何来支持定义“类”,并创建实例的呢?这就是我这篇博客将要解释的内容。

    Jscript中并不支持与传统语言一模一样的类的概念,但是它使用构造器函数(constructor function)和prototype对象来模拟“类”。

    让我们先来定义一个这篇博客中将要用到的几个关键词:

    类(class):在传统的面向对象语言中,它是定义了对象的结构,包括对象包括的属性,属性的类型和对象的操作方法。在Jscript中,并没有这种类型的定义。(译注:在Jscript中并没有直接支持定义这样的类)

    构造器函数(Constuctor functions):能够被new关键字初始化的函数称为构造器函数或简称为构造器。它的工作就是初始化一个带任意属性的对象,这个对象在使用new关键字后被返回。(译注:我不也不清楚该如何翻译这个概念,它可以这样理解:它本身就是一个函数,同时它可以被认为是一个对象的构造器。)

    Prototype对象:在Jscript中,除了Object.prototype,每个对象(类型层面上,不是实例)都有带有一个被称为prototype对象的引用。在prototype里的所有属性(和方法),都会出现在每个对象的实例中。(译注:理解prototype的概念,对理解Jscript中的继承和性能提升有很重要的意义。)

    带着这些信息,我们来开始使用Jscript来实现第一个“类”。

    我们要来定义一个带有带有高和宽的矩形,并且要提供一个计算其面积的area方法。

    首先,我们要来定义一个类,但Jscript中不支持Class关键字。那我们该如何做呢?看下面的代码。

    定义一个构造器函数来初始所需的数据:

    function Rectangle (ht, wt) {

                this.height = ht;

                this.width=wt;

    }

    接下来是创建Rectangle对象

    var rect1 = new Rectangle(5,10);

    var rect2 = new Rectangle(2,4);

    然后定义一个函数来计算Rectangle的面积

    function computeArea(rObj) {

                return rObj.height * rObj.width;

    }

    调用该函数来计算面积:

    var rectArea = computeArea(rect1); //will return 50.

    但是这样做就不是一个严格意义上的面向对象了。一种更好的办法是在Rectangle对象中调用一个函数来直接返回它的面积。在类中添加一个函数是可行的,加上这个函数的话,Rectangle的构造器变成了这样:

    function Rectangle (ht, wt) {

                this.height = ht;

                this.width=wt;

    this.area = function() { return this.height * this.width;}

    }

    然后我们就可以这样调用计算它的面积了:

    var rect1Area = rect1.area(); // rect1.area() will return 50.

    var rect2Area = rect2.area(); // rect2.area() will return 8.

    但这样还不是一个最理想的面向对象的实现,还有更好的方式。在这里矩形对象中会有会个属性,height, width和area。height, width对于每个矩形对象实例来说,可能会有不同的值,但是area对于每个对象实例来说使用的都是相同的函数原形。这就意味着area方法对每个矩形对象实例来说是可以共享的,那我们为什么不那么做呢?

    我们可以做这张图片中得知prototype对象源来。(译注:图?)

    我们把area定义为Rectangle的一个属性:

    Rectangle.prototype.area = function() {return this.height * this.width;}

    rect1.area(); // will return 50.

    rect2.area(); // will return 8.

    从上面我们所做的可以总结出以下的一些信息:

    构造器会为类提供一个名称,和初始化每一个类的实现的属性。Prototype对象与构造器有关,prototype对象里定义的任何属性都被每个由于构造器实例化的对象所继承。因此prototype对象是一个最理想地方来存储像area这个所有对象都相同的属性。(常量)

    这样做具有以下一些优点:

    所有相同的方法(一次定义所有实例共享)被定义在prototype对象中可以被所有的实例共享。它可以大大减小内存的开销。

    当一个属性在对象实例被创建之后被加在prototype对象中。那么这个对象实例同样也会继承这些新加的属性。

    尽管所有的对象都能顺利的从prototype对象中读取属性,但是却无法修改它们,为什么会这样呢?

    如果通过rect1(实例)我们可以修改area属性,那么势必其它的对象实例(像rect2, rect3…)在调用area属性时也一样会受到影响。尽管如此,我们仍然可以在对象的prototype的生命周期内来修改它本身的属性,但不是在对象的实例上。当我们试图在对象的实例上修改prototype属性时,它的结果是在对象实例中动态的添加这个属性以覆盖prototype的相同属性。

    这只是一个开始,在接下来的文章中,我会来讨论实例属性和静态属性(类属性),实体方法和静态方法(类方法)。此外,我们还会来研究一下数据是如何被封装和继承的。

    希望你喜欢这篇博客。

    Thanks,

    Ritesh

    SDET, JScript Team

    阿不 译

    阿不 http://hjf1223.cnblogs.com
  • 相关阅读:
    Chapter 03Using SingleRow Functions to Customize Output(03)
    Chapter 03Using SingleRow Functions to Customize Output(01)
    Chapter 04Using Conversion Functions and Conditional ExpressionsNesting Functions
    Chapter 04Using Conversion Functions and Conditional ExpressionsGeneral Functions
    Chapter 11Creating Other Schema Objects Index
    传奇程序员John Carmack 访谈实录 (zz.is2120)
    保持简单纪念丹尼斯里奇(Dennis Ritchie) (zz.is2120.BG57IV3)
    王江民:传奇一生 (zz.is2120)
    2011台湾游日月潭
    2011台湾游星云大师的佛光寺
  • 原文地址:https://www.cnblogs.com/hjf1223/p/924836.html
Copyright © 2011-2022 走看看