记载一个phper的历程!http://phperwuhan.blog.phpchina.com
JavaScript中的类定义与继承
2008-04-15 08:54:26 / 个人分类:javascript/dom
来源:http://www.phpchina.com/54842/viewspace_27479.html
*鉴于前面一片写JS的文章只是自己初学是自己测试用的代码,没有总结,不好理解,
这篇则是参考《Javascrīpt高级程序设计》里关于类定义的部分进行测试总结的,
应该能好理解一些。大家也可以参考一下该书。
这里先不讨论继承,
什么是类(Class)? 什么是对象(Object)?
在Java中,形如
public class MyClass{.......}
的定义,称类型MyClass为类(Class),而形如
MyClass myClassObj = new MyClass();
的定义, 则称变量 myClassObj是类MyClass的一个对象(Objcet)
或实例(instance)。
而EMCscrīpt中类是如何定义的,其中this,prototype又有何作用?这里讨论一下。
结果先写在前面: 定义方法如下:
//基类定义
function MyClass(){
this.nonSharedSimpleDataTypeMemeber = ???;
this.nonSharedObjectMember = new Object();
this.nonSharedObjectMemeber = {[JSON_Object]};
//For Example: var p = new Object();
// function OneClass(){this.person = p;};
this.sharedObjectMember1 = pointTo(another Existent);
}
MyClass.staticMemeber = ???;
MyClass.prototype.nonSharedSimpleDataTypeMember = ???;
MyClass.prototype.sharedObjectMember2 = ???;
//子类定义
function SubClass(){
MyClass.call(this);
this.memeberToCovered = ???
}
SubClass.prototype = new MyClass();
SubClass.prototype.memeberToCovered = ???
因此,在用JS定义类的时候,
> 不共享的简单类型数据成员可以用this定义也可以用prototype定义,
> 不共享的对象类型数据成员可以用this定义(但不要是类外部定义对象的引用,如上面的sharedObjectMember1),
> 共享的对象数据类型成员可以用prototype定义, 因此,函数最好都在prototype中定义,
因为用this定义将会函数在类实例之间不共享,造成内存浪费。
> 此外,还有 类“static” 成员,方法, 如 MyClass.staticMemeber, 它只能用 【类名】.【成员名】
的方式调用, 而不能是 【对象名】.【成员名】。
*/
function print(n,s){
document.open();
document.writeln(n+"="+s+"<br />");
document.close();
}
function println(s){
document.open();
document.writeln(s);
document.close();
}
/*****************************************************************************
定义区 && 讨论区
******************************************************************************/
/**
* 1> 用JOSN定义的如下Person不是类, 而是一个匿名类的唯一一个实例对象。
* 这种定义方式在开发JS库时经常用到,可以看作是一个Singleton模式类的唯一对象。
* 以下代码等同于:
* var Person = new function(){ //注意: 这里有个 new 关键字,new的function是个匿名类
* this.name = "zhang",
* this.sayHello = function(){
* println(this.name+"is say 'hello'<br />");
* }
* }
* 2> 用JOSN的方式来定义对象时,已经使用了关键字new,这一点需牢记。
* 3> Javascrīpt中的对象没有prototype属性,而类有prototype属性。
*/
var Person = {
name:"zhang",
sayHello:function(){
println(this.name+" is say 'hello'<br />");
}
}
/**
* 4> prototype中若有与this定义同名的属性,将以this定义的为主。因为在new的时候,
* 先将prototype的所有属性都拷贝给new出来的对象(简单数据类型是拷贝,对象是引用)
* 然后在执行构造函数,也就是先prototype再this。
* 5> 形如 Car.color 定义的属性只能以这种方式定义和访问,可以和this定义的重名,互不影响。
* 6> this关键字指向的是 在 new 的时候,new出来的对象,这一点要牢记。
* 7> 在Car的构造函数中使用this定义的变量,除非是引用已有的对象(不是新new的对象),
* 它们在实例对象中将相互对立,互不影响。
* 8> 有prototype定义的属性(对象,函数)在new时全部都是引用传递,故它们将在所有的
* 对象之间共享并相互影响。
*/
var thisArr = [211,222];
function Car(){
this.color="red";
this.price=1000;
this.arrObj0 = new Array(11,12); //因为有new,所以每个对象的此成员变量都相互独立,互不影响。
this.arrObj1= [111,122];//因为JSON定义方式本身包含new关键字,故同上,
this.arrObj2 = thisArr;//这种方式是引用外部已有对象,而不重新new,故可以被所有类对象共享
//alert(this.prototype);//undefined
}
Car.color = "blue";
Car.name="ShangHai DaZhong"; //只能以 Car.name形式访问,而不能以 objCar.name的形式访问。
Car.prototype.color="yellow";
Car.prototype.pNum = 123;
Car.prototype.pArrObj0 = new Array(11,22);
Car.prototype.pArrObj1 = [101,202];
var arr = [201,202];
Car.prototype.pArrObj2 = arr;
//以上3条prototype属性定义语句不管现在是new还是引用,但其属性值在赋值后都已经是引用,
//而在new对象时还会将引用值复制给类对象,所以还是引用
function Car1(){
Car.call(this);
this.arrObj1 = [999,888];
}
Car1.prototype = new Car();
Car1.prototype.pArrObj1 = [555,666];
/******************************************************************************
测试代码区
******************************************************************************/
print("Person.name",Person.name);
Person.sayHello();
print("Person.prototype",Person.prototype);//对象没有prototype属性
//var ōPerson = new Person();//不能够new,因为 Person本身就是对象而不是类。
print("Car.price",Car.price);
//当new Car的时候, 貌似先 将 prototype 里的属性先复制给new开辟的对象,然后才执行构造函数,将所以它不能覆盖Car()中定义的color属性,
//outputs "undefined", so define like "this.price=1000" can not
//outputs "blue", so Car.color can TREAT AS the STATIC member in Java.
//It will share by all instance of the Car class
print("Car.color",Car.color);
var oCar1 = new Car();//outputs "blue"
print("oCar1.color",oCar1.color);//outputs "red"
print("Car.prototype.color",Car.prototype.color);//outputs "yellow"
//outputs "red", this means that
var oCar2 = new Car();
print("oCar1.name",oCar1.name);//undefined
println("<span class='title'>----------------------------------this-----------------------------------</span><br />");
println("<span class='comment'>//this.SimpleDataType = SimpleData;</span><br />");
print("oCar1.price",oCar1.price); //outputs 1000
oCar2.price=9999;
print("oCar2.price",oCar2.price); //outputs 9999
print("oCar1.price",oCar1.price); //outputs 1000
println("<span class='comment'>//this.object = new Object();</span><br />");
print("oCar1.arrObj0", oCar1.arrObj0);
oCar2.arrObj0.push(13);
print("oCar2.arrObj0", oCar2.arrObj0);
print("oCar1.arrObj0", oCar1.arrObj0);
println("<span class='comment'>//this.object = {[JSON_Define_Object]}</span><br />");
print("oCar1.arrObj1", oCar1.arrObj1);
oCar2.arrObj1.push(333);
print("oCar2.arrObj1", oCar2.arrObj1);
print("oCar1.arrObj1", oCar1.arrObj1);
println("<span class='comment'>//this.object = pointTo(anotherObject)</span><br />");
print("oCar1.arrObj2", oCar1.arrObj2);
oCar2.arrObj2.push(333);
print("oCar2.arrObj2", oCar2.arrObj2);
print("oCar1.arrObj2", oCar1.arrObj2);
println("<span class='title'>----------------------------------prototype---------------------------</span><br />");
println("<span class='comment'>//UserClass.prototype.SimpleDataType = SimpleData;</span><br />");
print("oCar1.pNum",oCar1.pNum);
oCar2.pNum=321;
print("oCar2.pNum",oCar2.pNum);
print("oCar1.pNum",oCar1.pNum);
println("<span class='comment'>//UserClass.prototype.object = new Object()</span><br />");
print("oCar1.pArrObj0",oCar1.pArrObj0);
oCar2.pArrObj0.push(33);
print("oCar2.pArrObj0",oCar2.pArrObj0);
print("oCar1.pArrObj0",oCar1.pArrObj0);
print("Car.prototype.pArrObj0", Car.prototype.pArrObj0);//outputs 11,22,33, 由于是对象引用,所以全部相互影响。
println("<span class='comment'>//UserClass.prototype.object = {JSON_Define_Object:[]}</span><br />");
print("oCar1.pArrObj1",oCar1.pArrObj1);
oCar2.pArrObj1.push(103);
print("oCar2.pArrObj1",oCar2.pArrObj1);
print("oCar1.pArrObj1",oCar1.pArrObj1);
println("<span class='comment'>//UserClass.prototype.object = pointTo(anotherObject)</span><br />");
print("oCar1.pArrObj1",oCar1.pArrObj2);
oCar2.pArrObj2.push(301);
print("oCar2.pArrObj2",oCar2.pArrObj2);
print("oCar1.pArrObj1",oCar1.pArrObj2);
println("<span class='comment'>//inherit test</span><br />");
var car1 = new Car1()
for(var i in car1){
print("car1["+i+"]",car1[i]);
}
推荐 收藏 导入论坛 等级(0) 编辑 管理 查看(94) 评论(0) 评分(0/0)
TAG: