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


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

    1、构造函数与私有成员

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

      

    
    

    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'

    
    

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

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

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

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

    2、对象字面量与私有性

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

      

            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'    

    3、原型和私有性

      以上的两种方法,都有一个共同的问题,就是没实例化一个对象都会创建一次私有成员。那有没有一种方法,可以将一些常用的私有成员只创建一次呢。答案就是利用原型。原型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'     

    内存情况如下图的第二部分。第一部分为第一种情况。可以看到,和第一种比,会减少一些内存。

    第一、第二个console.log为undefined原因和第一种情况是一样的。

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

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

  • 相关阅读:
    Quora的技术探索
    基于移动互联网的电子商务个性化推荐的一些思考
    想个法子找出性能差的SQL
    结束——2012年微软精英挑战赛
    sql 查询时间执行长的sql语句
    NET好书盘点
    最后两个编程题
    网络七层协议
    使用WCF创建Restful服务
    一步一步学Entity FrameWork 4
  • 原文地址:https://www.cnblogs.com/dq-Leung/p/4326427.html
Copyright © 2020-2023  润新知