以下均为个人理解,如有不妥,请及时指正。
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”,”
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”,”
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();