js 代码
 
  1. //类的定义就应该这样  
  2.     function myClass(name,value){  
  3.         //私有变量name,value  
  4.         //私有函数  
  5.         var myGetName = function(){return name};  
  6.         var mySetName = function(aName){name = aName};  
  7.           
  8.         //操作私有成员的特权函数  
  9.         this.getName =  function(){return myGetName()};  
  10.         this.setName = function(aName){mySetName(aName)};  
  11.           
  12.         this.getValue = function(){return value};  
  13.         this.setValue = function(aValue){value = aValue};  
  14.       
  15.         //类的公共属性  
  16.         this.openNum = '20053572';    
  17.     }  
  18.     //类的公共属性  
  19.     myClass.prototype.openScore = 100;  
  20.     //类的公共方法  
  21.     myClass.prototype.callName = function(){  
  22.         alert('my name is '+ this.getName());  
  23.     }  
  24.     //然后实例化一个对象  
  25.     var myObj = new myClass('xombat','1');  
  26.     myObj.callName();  
  27.       
  28.       
  29.     //类的继承  
  30.     mySubClass = function (name,value){  
  31.         //调用构造函数  
  32.         myClass.call(this,name,value);  
  33.   
  34.     };  
  35.       
  36.     //使用指定原型的方式继承  
  37.     mySubClass.prototype = new myClass();  
  38.     var superclass = mySubClass.prototype;  
  39.     superclass.constructor = mySubClass;  
  40.       
  41.     //重定义父类的方法  
  42.     superclass.callName = function(){  
  43.         //var btn = Ext.get('btn');  
  44.         Ext.MessageBox.show({  
  45.             width:200,  
  46.             animEl:"btn",  
  47.             msg:'xombat == good',  
  48.             title:'oh ,king!'  
  49.         });  
  50.     }  
  51.       
  52.     var mySubObj = new mySubClass('ixombat','2');  
  53.     Ext.onReady(mySubObj.callName,mySubObj);  
以上的方式实现了oop思想:类封装,私有成员,公共成员,继承。  
下面以下面这个分析为例:
出自:http://extjs.com/learn/Tutorial:Application_Layout_for_Beginners_%28Chinese%29

我进行了一下修改,修改后为(改动地方用红色标出)
js 代码
  1. // 创建命名空间
  2. Ext.namespace('myNameSpace');
  3. // 创建一个类(而不是应用程序)
  4. myNameSpace.myClass = function() {
  5. // 元素还没创建,未能访问
  6. // 私有变量
  7. var btn1;
  8. var privVar1 = 11;
  9. // 私有函数
  10. var btn1Handler = function(button, event) {
  11. alert('privVar1=' + privVar1);
  12. alert('this.btn1Text=' + this.btn1Text);
  13. };
  14. // 公共空间
  15. return {
  16. // 公共的属性,如,要转译的字符串
  17. btn1Text: 'Button 1'
  18. // 公共方法
  19. , init: function() {
  20. btn1 = new Ext.Button('btn1-ct', {
  21. text: this.btn1Text
  22. , handler: btn1Handler
  23. });
  24. }
  25. };
  26. };//(); //程序底部

  27. //添加下面这行,用来实例一个对象
  28. myNameSpace.app = new myNameSpace.myClass();


这是Ext中给的一个面向对象的代码模板,return 上面的是私有变量和私有方法,return下面的是公共变量和公共函数。其中还引入一个特权的概念,在函数体中定义的公共函数(为特权函数)可以访问私有 变量/方法(即为特权函数的特点),而其它的公共函数不能访问私有变量/方法。

解读名字空间:

名字空间的概念其实也是一些object对象,比如我定义myNS.xmlNS:
js 代码
  1. Ext.namespace('myNS.xmlNS');

其实就是定义了一个myNS = new Object;(如果Ext中myNS还未定义的话)
然后myNS.xmlNS = new Object;

解读实例的对象:
app为被实例的对象,app其实也就是一个函数的返回值,返回的是个对象直接量。

解读public / private访问权限:
因此函数执行完之后,return返回的这些对象被app引用,所以没有被回收,因此被称为public的,并能从外部查看。

而return 之上的为private的,是因为function执行完之后,这些局部变量(其中未被public变量引用的)被释放掉了,无法再从外部读取。但是他们为return后的函数做了些计算准备,因此还是有用的,相当于私有变量/方法。

构造函数:
至于构造函数,一般oo语言的构造函数是用来生成对象的,而这整个function正好有这个效果。

不足:
但是js无法模仿oo的所有特性:oo的公共方法应该可以访问私有方法,但是一般情况下js中却不能直接用公共方法调用私有方法,因为构造函数已经执行完了,私有方法的引用已经被释放了。因此:
1.引入一个特权概念,存在于构造函数中的公共方法叫做特权函数,比如上面代码中的init函数,虽然构造函数运行完了,但他的btn1handler仍持有那个函数的引用,因此他可以调用内部的方法。而如果这样:
js 代码
  1. Ext.apply(myNameSpace.app, {
  2. btn1Text:'Taste 1'
  3. , init: function() {
  4. try {
  5. btn1 = new Ext.Button('btn1-ct', {
  6. text: this.btn1Text
  7. , handler: btn1Handler
  8. , scope: this
  9. });
  10. }
  11. catch(e) {
  12. alert('错误: "' + e.message + '" 发生在行: ' + e.lineNumber);
  13. }
  14. }
  15. });

,通过使用apply方法改变app类的init函数实现,却会出现错误。因为新的btn1Handler是一个新的对象里面的,他没有引用到原来的那个 btn1Handler(也无法引用到,因为构造函数已经运行完了,里面的btn1Handler已经释放了)。说明,一般情况下,公共方法无法调用私有 方法。
2.即使是特权函数,里面的btn1Handler仍然只是那个函数的引用,对于他引用的这个函数,使用的数据无法,....
评论
发表评论

您还没有登录,请登录后发表评论

xombat
搜索本博客
存档
最新评论