Programming Life
相信不能相信的,完成不能完成的。矛盾,就象征进步。
posts - 151,comments - 7,trackbacks - 0

以下均为个人理解,如有不妥,请及时指正。
1、  定义和实现类之间的继承

A、 通过 直接引用和函数调用

function Child(name,age,sex)

{

this.name = name;

this.age = age;

  this.sex = sex;

  this.toString = function()

  {

window.alert(this.name+"/"+this.age+"/"+this.sex);

}

}

function Guy(name,age,sex)

{

this.Super = Child;

this.Super(name,age,sex);

}

var __child = new Guy("me","10","M");

 __child.toString();

解释:

继承的过程先是将Child的对象原型赋给 Guy 下的 Super 方法, 然后在执行完 Child 的构造函数后, Child的属性就被自动地加到了 Guy 的属性列表中.这主要是由于在 Guy 中通过 this 来调用的 Super(也就是 Child) 构造函数造成的, 通过此种方式调用 Child 构造函数时, JavaScript 解释器会把 Child 中的 this 与 Guy 中的 this 理解成位于同一个作用域下的 this 关键字, 所以就产生了继承的效果。当然我们也可以用InheritsForm,base等关键字来描述继承父类。

另外, 需要说明的是, 对于任何一个实例化的对象, 你任意地为它添加属性或方法, 如下所示:

  var newGuy = new Gue();
  newGuy.addprop = "added property to instance object";

很明显, 通过此种方式添加的属性和方法只对当前实例化对象有效, 不会影响所有的同类型对象实例. 无疑, 它是你创造的一个独一无二的对象实例.

 

B、 通过prototype 关键字

function Guy(name,age,sex)

{

  this.name = name;

  this.age = age;

  this.sex = sex;

}

Guy.prototype = new Child();

var guy = new Guy(“me”,”10”,”M”);

guy.toString();

如果我们要覆盖父类也就是Child的tostring()方法,可以这样定义:

Guy.prototype.toString = function()

{

  window.alert(“…….”);

}

这里说明下:

先定义一个类的prototype 为另外一个类,也就是定义该类为某个类的子类。

再通过Class.prototype.functionName = function(Args)来实现方法覆盖。

整个Guy的代码如下:
function Guy(name,age,sex)

{

  this.name = name;

  this.age = age;

  this.sex = sex;

}

Guy.prototype = new Child();

Guy.prototype.toString = function()

{

  window.alert(“…….”);

}

var guy = new Guy(“me”,”10”,”M”);

guy.toString();

C、 但是javascript 中好象不支持多深度的继承。也就是说无法实现AàBàC当中的A向上调用C的方法。

2、  关于prototype 的几点理解

A.         

var AjaxPro.IFrameXmlHttp.TestClass = new Function();

 

AjaxPro.IFrameXmlHttp.TestClass.prototype.abort = function()

{

window.alert("this is AjaxPro.IFrameXmlHttp ");

}

 

AjaxPro.IFrameXmlHttp.TestClass.prototype = {

stopMe: function(){

      window.alert("Oh,don't stop me");

  },

  reset: function(){

    window.alert(“Oh,is reseting now,please waite”);

}

 };

var Test = new AjaxPro.IFrameXmlHttp.TestClass();

Test.abort();

Test.stopMe();

在两者同时出现的时候,请将外部定义的prototype 函数放在内部定义的prototype = {}的后面,否则后者会覆盖前者。

 

B.        如果定义了B.prototype = new A() //new A; ,那么当调用B.prototype.function = function() 时,就可以覆盖A中的方法或是新定义属于B的方法。这个过程就象是如下:

prototype = new A() 语句时,就把A 给了B.prototype 属性了。再使用B.prototype.function  = function(){} 时,就类似的 A.function = function(){},因为前面我们已经将B.prototype = new A()了。

 

C.        通过 this关键字定义的属性和方法是同对象本身处于同一个地址空间内的; 而通过 prototype 定义的属性和方法, 是通过所谓的 "原型链" 进行管理的, 其下的的属性和方法不位于同一个地址空间之间, 当其调用这种属性或方法时, 必须通过 "链表" 才能索引到其下的某个属性或方法. 也就说, 调用以原型方式定义的属性和方法会有一个类似于链表的 "回溯" 操作.

 

D.       构造过程中,原型对象是一次性生成的;新对象只持有这个原型实例的引用 (并用“写复制”的机制来存取其属性),而并不再调用原型的构造器。

 

E.        最好的理解就是,prototype 表示 附加给我的东西,我便和你所有属性和方法的指针指向一致。在我申明和你相同的属性时,实际上是覆盖了你对应的属性。

例如:

Function A()

{

        This.name  = “is A”;

}

Function B()

{

        This.name = “is B”;

}

//A对象实例赋植给prototype,无形之中创建了个指针链。

B.prototype = new A();

//由于 _bb和new A()拥有同名name ,所以编译器会认为同一要素,因此就覆盖A中的name.

Var _bb = new B();

 

 

3、  Prototype.js 中对AddNameSpace 理解

最初代码如下:

if(!window.addNamespace) {

    window.addNamespace = function(ns) {

        var nsParts = ns.split(".");

        var root = window;

 

        for(var i=0; i<nsParts.length; i++) {

            if(typeof root[nsParts[i]] == "undefined")

                root[nsParts[i]] = {};

            root = root[nsParts[i]];

        }

    }

}

 

其中root[nsParts[i]] = {};

可以改为如下两种中的任何一种

A、   root[nsParts[i]] = new Object();

B、   root[nsParts[i]] = new Function();

由于Function 继承自Object,所以两个都可以。

// by 3zfp.zeng 2006.03.18

 

另外一种方法为:

if(!window.addNamespace) {

    window.addNamespace = function(ns) {

        var nsParts = ns.split(".");

        var root = "window";

        for(var i=0; i<nsParts.length; i++) {

            root = root+"."+nsParts[i];

            if( eval(" typeof "+ root+"=='undefined'") == true)

                eval(root+"= new Function()");

        }

    }

}

4、  prototype.js 中对Class 类的理解

源代码如下:

var Class = {

    create: function() {

        return function() {

            if(typeof this.initialize == "function")

                this.initialize.apply(this, arguments);

        }

    }

}

可以改为:

var Class = function() //function Class()

{

        this.create =  function() {

       return function()

{

           if(typeof this.initialize == "function")

              this.initialize.apply(this, arguments);

       }

    }

}

进一步的改为(在只是声明不带参数的函数/对象是使用):

var Class = function()

{

        this.create =  function()

{

           return new Function();

        }

}

5、  apply 方法             通过该方法可以实现函数 重载 功能。

应用某一对象的一个方法,用另一个对象替换当前对象。

apply([thisObj[,argArray]])

参数

thisObj

可选项。将被用作当前对象的对象。

argArray

可选项。将被传递给该函数的参数数组。

说明

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。

如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

    例子:

    Point2D.prototype.distance = function()  

{

       if (arguments[0] instanceof Point2D)

       {

           return this._point_distance.apply(this, arguments);

           含义为:

由_point_distance 函数替换distance函数,并将arguments

           等参数信息复制过去。

       }

       else if (arguments[0] instanceof Vector2D)

       {

           return this._vector_distance.apply(this, arguments);

       }

       else

       {

           throw new Error("Argument Error!");

        }

    }

6、  函数内部直接套function和通过this来指代funcion之间的区别

var Kinds = function()

{

  function DownA()            //内部私有函数,不能被外部调用。

  {

      alert("is me DownA");

  }

  function DownB()                //内部私有函数,不能被外部调用。

  {

      DownA();

  }

  this.DownC = function()     //该 this 指示 Kinds

  {

      this.DownCC = function()    //该 this 指示 Downc

      {

         new Kinds().DownD();

         DownB();

      }

      Alert(“is me DownC”);

  }

  this.DownD = function()     //该 this 指示 Kinds

  {

      alert("is me DownD");

  }

}

var t = new Kinds();

var d = new t.DownC();

d.DownCC();

PrintOuts:

is me DownC

is me DownD

is me DownA

DownB,DownA 等函数只能是通过内部调用来实现。这样就保证了其方法的内部private性。而通过使用 this.FunctionName = function() 来定义的则可以使用”.”隔号来实现。 其实这个和类 / 类型作用域 类似.

7、  prototype.js 中 extend 含义:让所有的对象都继承自object对象且复制给Object 并返回。

8、  AjaxPro 解析过程:

A、 定义可以被生成客户端对象的type,也就是将在客户端生成类似如下代码的代码段:

AjaxPro.Utility.RegisterTypeForAjax(typeof(Examples.Classes.Demo));

该代码会在客户端生成如下js 块

<script type="text/javascript" src="/AJAXDemo/ajaxpro/AJAXDemo.Examples.Classes.Demo,AJAXDemo.ashx"></script>

 

B、 而我们恰巧在web.config 文件中定义了 对于ajaxpro/*.ashx 的请求都由AjaxPro.AjaxHandlerFactory, AjaxPro 来处理。这样的话 就可以对与.ashx文件可以response.write 出一段js 代码了。该代码如下:

 

addNamespace("AJAXDemo.Examples.Classes");

AJAXDemo.Examples.Classes.Demo_class = Class.create();

AJAXDemo.Examples.Classes.Demo_class.prototype = (

new AjaxPro.Request()).extend(

{

    GetMyClass: function(callback) {

        return this.invoke("GetMyClass", {}, callback);

    },

    GetMyInheritedClass: function(callback) {

        return this.invoke("GetMyInheritedClass", {}, callback);

    },

    PutMyClass: function(c, callback) {

        return this.invoke("PutMyClass", {"c":c}, callback);

    },

    GetPerson: function(callback) {

        return this.invoke("GetPerson", {}, callback);

    },

    initialize: function() {

        this.url = "/AJAXDemo/ajaxpro/AJAXDemo.Examples.Classes.Demo,AJAXDemo.ashx";

    }

}

)

AJAXDemo.Examples.Classes.Demo =

new AJAXDemo.Examples.Classes.Demo_class();

posted on 2007-11-26 04:05 Prog 阅读(543) 评论(0)  编辑 收藏 引用 网摘 所属分类: JavaScript

只有注册用户登录后才能发表评论。
网站导航: