首页 > 代码库 > JavaScript面向对象(2)--属性分析及验证

JavaScript面向对象(2)--属性分析及验证

1、私有属性分析

 1 function MyClass() 2 { 3     // 私有属性 4     var privateName = "private"; 5  6     this.setPrivateName = function(value) 7     { 8         privateName = value; 9     }10         11     this.getPrivateName = function()12     {13         return privateName;14     }15 }16 17 var object1 = new MyClass();18 var object2 = new MyClass();19 object1.setPrivateName("object1");20 object1.setPrivateName("object2");21 //弹出object122 alert(object1.getPrivateName());23 //弹出object224 alert(object2.getPrivateName());

 

以上代码证明私有属性不能被不同对象共享,可以正常使用

2、window属性、方法分析

 1 function MyClass() 2 { 3     // window属性 4     windowName = "window"; 5  6     this.setWindowName = function(value) 7     { 8         windowName = value; 9     }10         11     this.getWindowName = function()12     {13         return windowName;14     }15 }16 17 var object1 = new MyClass();18 var object2 = new MyClass();19 object1.setWindowName("object1");20 object1.setWindowName("object2");21 //弹出object222 alert(object1.getWindowName());23 //弹出object224 alert(object2.getWindowName());

 

以上代码证明Window属性被不同对象共享

下面还有更意外的情况

 1 function MyClass1() 2 { 3     // Window属性 4     windowName = "window";     5      6     this.setWindowName = function(value) 7     { 8         windowName = value; 9     }10         11     this.getWindowName = function()12     {13         return windowName;14     }15     16     windowMethod = function()17     {18         alert("MyClass1");19     }20     21     this.visitWindowMethod = function()22     {23         windowMethod();24     }25 }26 27 function MyClass2()28 {29     // Window属性30     windowName = "window";31     32     this.setWindowName = function(value)33     {34         windowName = value;35     }36         37     this.getWindowName = function()38     {39         return windowName;40     }41     42     windowMethod = function()43     {44         alert("MyClass2");45     }46     47     this.visitWindowMethod = function()48     {49         windowMethod();50     }51 }52 53 var object1 = new MyClass1();54 var object2 = new MyClass2();55 object1.setWindowName("object1");56 object1.setWindowName("object2");57 //弹出object258 alert(object1.getWindowName());59 //弹出object260 alert(object2.getWindowName());61 //弹出MyClass262 object1.visitWindowMethod();63 //弹出MyClass264 object2.visitWindowMethod();

 

好吧,windowName和windowMethod虽然在类内定义,但实际上等于给window定义了windowName和windowMethod,所有的访问也都是针对window对象的属性和方法,所以当另一个对象或者类定义了相同的windowName和windowMethod时,之前的定义就被覆盖了。

windowName和window的属性没有任何区别,windowMethod却和window的方法有些区别。windowMethod可以访问类内的私有属性和私有方法,这是window的方法做不到的。这可是个不错的特性,不过这个特性可不好用。

让我们再做个实验吧

 1 function MyClass1() 2 { 3     // private属性 4     var privateName = "MyClass1Private";     5      6     windowMethod = function() 7     { 8         alert(privateName); 9     }10     11     this.visitWindowMethod = function()12     {13         windowMethod();14     }15 }16 17 function MyClass2()18 {19     // private属性20     var privateName = "MyClass2Private";    21     22     windowMethod = function()23     {24         alert(privateName);25     }26     27     this.visitWindowMethod = function()28     {29         windowMethod();30     }31 }32 33 var object1 = new MyClass1();34 var object2 = new MyClass2();35 //弹出MyClass2Private36 object1.visitWindowMethod();37 //弹出MyClass2Private38 object2.visitWindowMethod();

 惊讶吗,访问的竟然都是MyClass2的属性。

windowName和windowMethod要慎用,这种不加var的定义方法会是个很大的坑,所以建议大家不要使用。

3、this定义的公有属性分析

 1 function MyClass() 2 { 3     // public 4     this.publicName = "public";     5 } 6  7 var object1 = new MyClass(); 8 var object2 = new MyClass(); 9 object1.publicName = "object1";10 object2.publicName = "object2";11 //object112 alert(object1.publicName);13 //object214 alert(object2.publicName);

 这个就没什么好说的了,和其他语言一样。

4、prototype定义的公有属性分析

 1 function MyClass() 2 { 3      4 } 5 MyClass.prototype.publicName = "public"; 6 var object1 = new MyClass(); 7 var object2 = new MyClass(); 8  9 //public10 alert(object1.publicName);11 //public12 alert(object2.publicName);13 object1.publicName = "object1";14 object2.publicName = "object2";15 //object116 alert(object1.publicName);17 //object218 alert(object2.publicName);19 //public20 alert(MyClass.prototype.publicName);21 22 object1.constructor.prototype.publicName = "object1prototype";23 object2.constructor.prototype.publicName = "object2prototype";24 //object125 alert(object1.publicName);26 //object2prototype27 alert(object1.constructor.prototype.publicName);28 //object229 alert(object2.publicName);30 //object2prototype31 alert(object2.constructor.prototype.publicName);32 //object2prototype33 alert(MyClass.prototype.publicName);

 

这个例子相信也产生了一些意外,这和JavaScript的对象生成方式有关,我们可以把JavaScript的类看作是一个模板,每次生成对象时都将在类内定义的属性、方法和类外通过prototype定义的属性、方法(私有属性、私有方法、公有属性、公有方法)拷贝到对象中不拷贝类外定义的静态属性和静态方法。

拷贝完成后对象和模板唯一的关联就是constructor,对象可以通过constructor访问模板。

这下上面的例子应该好理解了,constructor.prototype.publicName是更改了模板中的属性,object1.publicName只是改变了object1对象这个拷贝中的属性。

 

5、静态属性分析 

上面其实也解释了静态属性的原理,静态属性其实是MyClass这个模板的属性,只存在与模板之中,对象并不含有这个属性。对象想访问静态属性只能通过constructor。

 1 function MyClass() 2 { 3      4 } 5 MyClass.staticName = "static"; 6 var object1 = new MyClass(); 7 var object2 = new MyClass(); 8 object1.staticName = "object1"; 9 object2.staticName = "object2";10 //object111 alert(object1.staticName);12 //object213 alert(object2.staticName);14 //static15 alert(MyClass.staticName)16 17 object1.constructor.staticName = "object1";18 object2.constructor.staticName = "object2";19 //object220 alert(object1.constructor.staticName);21 //object222 alert(object2.constructor.staticName);23 //object224 alert(MyClass.staticName);

 

这个例子很好的说明了静态属性的使用方式,对象要通过constructor访问,类可以直接访问。上面的object1.staticName = "object1"其实给object1添加了一个名为staticName的公共属性,并没有为静态属性赋值。

JavaScript面向对象(2)--属性分析及验证