javascript王者归来公有和私有:属性的封装

       前面已经说过,封装性是面向对象的一个重要特性。所谓的封装,指得是属性或方法可以被声明为公有或者私有,只有公有的属性或方法才可以被外部环境感知和访 问。曾经有人说JavaScript不具备封装性,它的对象的属性和方法都是公有的,其实,持这个观点的人只看到了JavaScript函数的对象特征, 而忽视了JavaScript函数的另一个特征——闭包。

利用闭包的概念,JavaScript中不但有公有和私有的特性,而且它的公有和私有性,比起其它各种面向对象语言毫不逊色。下面给出一个例子:

例21.2 对象的公有和私有特性

function List()

{

       var m_elements = []; //私有成员,在对象外无法访问

      

       m_elements = Array.apply(m_elements, arguments);

      

//公有属性,可以通过“.”运算符或下标来访问

       this.length = {

              valueOf:function(){

                     return m_elements.length;

              },

              toString:function(){

                     return m_elements.length;

              }

       }

       this.toString = function()

       {

              return m_elements.toString();

       }

       this.add = function()

       {

              m_elements.push.apply(m_elements, arguments);

       }

}

       function List定义了一个List类,该类接受一个参数列表,该列表中的成员为List的成员。m_elements是一个私有成员,在类的定义域外部是无法访 问的。this.length、this.toString和this.add是公有成员,其中this.lenght是私有成员m_elements的 length属性的getter,在外部我们可以通过对象名的“.”运算符对这些属性进行访问,例如:

       var alist = new List(1,2,3);

       alert(alist);

       alert(alist.length);

       alist.push(4,5,6);

       alert(alist);

       alert(alist.length);

 小技巧:对象 的getter是一种特殊的属性,它形式上像是变量或者对象属性,但是它的值随着对象的某些参数改变而变化。在不支持getter的语言中,我们通常用 get<Name>方法来代替getter,其中<Name>是getter的实际名字,这种用法产生的效果和getter等 价,但是形式上不够简洁。ECMAScript v3不支持getter,但是可以用上面这种构造带有自定义valueOf和toString方法的对象来巧妙地模拟getter。

       例如,下面的两段代码基本上等价:

       //第一段代码:使用getName()方式

       function Foo(a, b)

       {

              this.a = a;

              this.b = b;

              this.getSum = function()

              {

                     return a+b;

}

       }

       alert((new Foo(1,2)).getSum()); //得到3

       //第二段代码:模拟getter

       function Foo(a, b)

       {

              this.a = a;

              this.b = b;

              this.sum = {

                     valueOf:function(){       return a+b},

                     toString:function(){return a+b}

}

       }

       alert((new Foo(1,2)).sum); //同样得到3

对 象的setter是另一个相对应的属性,它的作用是通过类似赋值的方式改变对象的某些参数或者状态,遗憾的是,ECMAScript v3不支持setter,并且目前为止也没有什么好的办法可以在JavaScript上模拟setter。要实现setter的效果,只有通过定义 set<Name>方法来实现。

原文地址:https://www.cnblogs.com/xinzhuangzi/p/4100588.html