javascript模式(1)--私有成员

  javascript是基于对象的一门语言,没有想java等语言那样子拥有封装的特性。可是javascript能够经过闭包来进行模拟。javascript

一、构造函数与私有成员java

  能够用构造函数造成一个闭包,实现内部成员的私有化。闭包

  

 
 

function Person(){
  //私有成员
  var country = 'cn';
  //特权方法
  this.getCountry = function(){
  return country;
  }
}
var man1 = new Person();
var man2 = new Person();
console.log(man1.country );//undefined
console.log(man2.country );//undefined
console.log( man1.getCountry() );//'cn'
console.log( man2.getCountry() );//'cn'函数

 

这个例子在内存中应该是这个样子的:this

也就是每实例化一次,都会建立私有成员。spa

man2.country之因此为undefined,是由于country不是对象的属性而是私有属性。因此没法经过这种原型链的方式去访问到,因此就是该对象没有这个属性。prototype

man2.getCountry()之因此能访问到,那就是由于闭包了。由于Person构造函数在运行完以后还有一个man2.getCountry()存在,因此不会将其做用域从内存中删除--从而造成了一个闭包。当运行man2.getCountry这条语句到return country;时,因为本身的做用域中并无country这个属性。因此顺着做用域链往上找。在上一级的做用域中找到而后返回。code

二、对象字面量与私有性对象

  原理和第一种同样,只是写法上不一样。blog

  

        var obj;
    (function(){
        //私有成员
        var name = 'quan';

        //公共成员部分
        obj = {
            getName: function(){
                return name;
            }
        }
    }())
    console.log( obj.getName() );//'quan'    

或者下面:

         var obj = (function(){
        //私有成员
        var name = 'quan';

        //公共成员部分
        return {
            getName: function(){
                return name;
            }
        };
    }())

    console.log( obj.getName() );//'quan'    

三、原型和私有性

  以上的两种方法,都有一个共同的问题,就是没实例化一个对象都会建立一次私有成员。那有没有一种方法,能够将一些经常使用的私有成员只建立一次呢。答案就是利用原型。原型prototype也是一个对象是函数的一个属性;是利用构造函数实例化一个对象以后,对象的一个属性__proto__。

  

    function Person(){
        //
    }
    Person.prototype = (function(){
        //原型中的私有成员
        var country = 'cn';

        //原型中的公有成员
        return {
            getCountry: function(){
                return country;
            }
        }
    }())
    var man1 = new Person();
    var man2 = new Person();
    console.log(man1.country);//undefined
    console.log(man2.country);//undefined
    console.log( man1.getCountry() );//'cn'
    console.log( man2.getCountry() );//'cn'     

内存状况以下图的第二部分。第一部分为第一种状况。能够看到,和第一种比,会减小一些内存。

第1、第二个console.log为undefined缘由和第一种状况是同样的。

第3、第四个log输出的缘由就稍稍有点不一样。首先,man1没有getCountry这个方法,因此沿着原型链在上一级的原型中找到getCountry方法而后调用getCountry方法。而后后面的部分就和第一种同样的原理了。就是闭包了。

可是这第三种方法也是有缺点的。那就是访问时要顺着原型链向上找,若是原型链很长,那也会变慢。

相关文章
相关标签/搜索