yunshichen

我相信人生是值得活的,尽管人在一生中必须遭受痛苦,卑劣,残酷,不幸和死亡的折磨,我依然深信如此.但我认为人生不一定要有意义,只是对一些人而言,他们可以使人生有意义. ---J 赫胥黎

javascript杂谈二:OO ?


    OO的三个概念是封装,继承和多态。

    强类型语言如C++或Java用private,protected和public三个关键字表征成员函数的作用域。js缺少这样的关键字,根据Douglas 的说法,js的方法有:

    private : 只能在类实例中访问的方法。
    privileged: 公开的能够访问类实例的私有变量,你可以替换或者删除privileged方法,但不能修改
    public : 公开方法,只能访问公开属性变量,不能访问类实例的私有变量。

    代码如下:

 
<html>
<script>
    
var Employee=function(sname,iage){
        
//private properties.
        var m_name=sname;
        
var m_title;
        
//public properties.
        this.age=iage;
        
//private methods.
        function sayHello(){
            alert(
"Hello,"+m_name);
        };
        
//privileged methods.
        this.getName=function(){
            
return m_name;
        };
        
this.setName=function(sname){
            m_name
=sname;
        };        
        
    };
    
//public methods.
    Employee.prototype.getAge=function(){
        
return this.age;
    };
    
    emp1 
= new Employee("test1",28);
    alert(
"emp1.name:"+emp1.getName());
    
//Reset private properties.
    emp1.setName("test 2");
    alert(
"emp1.name:"+emp1.getName());
    
//Replace privileged methods.
    emp1.setName=function(sname,stitle){
        m_name
=sname;
        m_title
=stitle;
    };
    emp1.getName
=function(){
        
return m_name+"::"+m_title;
    };
    
//Invoke replaced privileged methods.
    emp1.setName("Chen","Engineer");
    alert(
"emp1.name:"+emp1.getName());
    
    
//Invoke public methods.
    alert("emp1.age"+emp1.getAge());
    alert(
"emp1.age"+emp1.age);
    
    
    
    
</script>
</html>

  你很快会发觉,所谓的public方法根本不能访问私有变量,这令它的价值大打折扣。而出于数据封装的目的,使用public的变量似乎也颇为不妥。

  为了达到”将相关信息封装到类“的目的,有两种变通办法,第一种,只采用private变量和privileged方法:

    var Employee=function(sname,iage){
        
//private properties.
        var m_name=sname;
        
//privileged methods.
        this.getName=function(){
            
return m_name;
        };
        
this.setName=function(sname){
            m_name
=sname;
        };        
        
    };
    
//public methods.
    Employee.prototype.getAge=function(){
        
return this.age;
    };
    
    emp1 
= new Employee("test1",28);
    alert(
"emp1.name:"+emp1.getName());

  这种做法似乎很好,除了会带来性能的问题。因为每个实例自身都会创建两个方法。

  另一种做法以实用主义为宗旨。不是所有的私有属性都需要get/set方法的,这增加了代码编写者的额外负担。只需在设计类的时候约定哪些属性是私有的,类的使用者不应该直接去访问。约定的私有属性以__或者_打头。

  例如上面的版本可以重写为:

    var Employee=function(sname,iage){
        
//Actually all are public properties,but you shouldn't directly access _age.
        this.name=sname;
        
this._age=iage;        
    };
    
//public methods.
    Employee.prototype.getName=function(){
        
return this.name;
    };
    
//public methods.
    Employee.prototype.getAge=function(){
        
return this._age;
    };
    
    emp1 
= new Employee("test1",28);
    alert(
"emp1.name:"+emp1.name);
    alert(
"emp1.age:"+emp1.getAge());
    alert(
"emp1._age:"+emp1._age);


  正如你在代码中看到的,用_给变量命名并没有改变它的public性质,仅仅是一种约定而已。本例中的约定表示:你可以直接访问emp1.name,但你不应该直接访问emp1._age,该变量是私有变量。

  在YUI中采用了第二种做法,以实用为先。但是对Douglas来说,这似乎是个讽刺。他说js是世上最被误解的语言,他说js有完整的oo能力,但似乎,从他领导的YUI看不出这一点。




posted on 2008-08-22 17:35 Chenyunshi 阅读(468) 评论(1)  编辑 收藏 引用 所属分类: Web development

评论

# re: javascript杂谈二:OO ? 2008-08-24 11:51 戴尔电脑

没错,javascript只能算机遇对象,还不是面向对象的语言。  回复  更多评论   

只有注册用户登录后才能发表评论。
<2011年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(7)

随笔分类

随笔档案

文章分类

相册

搜索

最新评论

阅读排行榜

评论排行榜