函数中的私有变量和特权方法

Posted 叶祖辉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数中的私有变量和特权方法相关的知识,希望对你有一定的参考价值。

定义

  【1】【私有变量】
  任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。私有变量包括函数的参数、局部变量和在函数内部定义的其他函数


  【2】【特权方法】
  如果在函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量。而利用这一点,就可以创建用于访问私有变量的公有方法。有权访问私有变量和私有函数的公有方法称为特权方法。

 

创建方式

  【1】【构造函数】

  在构造函数内部定义所有私有变量和函数。然后,创建能够访问这些私有成员的特权方法。能够在构造函数中定义特权方法,是因为特权方法作为闭包有权访问在构造函数中定义的所有变量和函数。
    [缺点]必须使用构造函数模式来达到目的,且针对每个实例都会创建同样一组方法

技术分享
function MyObject(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
        alert(1)
        return false;
    }
    //特权方法
    this.publicMethod = function(){
        privateVariable++;
        return privateFunction();
    }
}    
new MyObject().publicMethod();//弹出1    
技术分享

 

  【2】【静态私有变量】

  通过在私有作用域中定义私有变量和方法来创建特权方法。
    [优点]私有变量和函数由实例共享,增强代码复用
    [缺点]每个实例都没有自己的私有变量

技术分享
(function(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
        alert(1)
        return false;
    }
    //在定义该构造函数时并没有使用函数声明,而是使用了函数表达式。且没有使用var关键字,使其成为全局变量。
    MyObject = function(){};
    //在原型上定义特权方法
    MyObject.prototype.publicMethod = function(){
        privateVariable++;
        return privateFunction();
    }
})();
new MyObject().publicMethod();//弹出1    
技术分享

    [另一个例子]

技术分享
(function(){
    var name = "";
    Person = function(value){
        name = value;
    };
    Person.prototype.getName = function(){
        return name;
    };
    //name变成静态的由所有实例共享的属性
    Person.prototype.setName = function(value){
        name = value;
    }
})();

var person1 = new Person("Nicholas");
console.log(person1.getName());//"Nicholas"
person1.setName("Greg");
console.log(person1.getName());//"Greg"

var person2 = new Person("Michael");
console.log(person1.getName());//"Michael"
console.log(person2.getName());//"Michael"
技术分享

 

作用

  【隐藏数据】:利用私有和特权成员,隐藏不应该被直接修改的数据

技术分享
function Person(name){
    this.getName = function(){
        return name;
    }
    this.setName = function(value){
        name = value;
    };
}
var person = new Person("Nicholas");
console.log(person.getName());//"Nicholas"
person.setName(‘Greg‘);
console.log(person.getName());//"Greg"
/*以上代码的构造函数定义了两个特权方法:getnName()和setName()。这两个方法都可以在构造函数外部使用,而且有权访问私有变量name。但在Person构造函数外部,没有任何办法访问name。由于这两个方法都是在构造函数内部定义的,它们作为闭包能够通过作用域访问name。*/
技术分享

 

单例

  【单例定义】单例是指只有一个实例的对象


  【单例创建方式】javascript是以对象字面量的方式来创建单例对象的

 

针对于单例的私有变量和特权方法的两种模式

   【1】【模块模式】:使用一个返回对象的匿名函数。在这个匿名函数的内部,首先定义了私有变量和函数。然后,将一个对象字面量作为函数的值返回。返回的对象字面量中只包含可以公开的属性和方法。由于这个对象是在匿名函数内部定义的。因此它的公有方法有权访问私有变量和函数。从本质上讲,这个对象字面量定义的是单例的公共接口。这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时非常有用。

技术分享
var singleton = function(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
        alert(1)
        return false;
    }
    //特权方法和属性
    return{
        publicProperty: true,
        publicMethod : function(){
            privateVariable++;
            return privateFunction();
        }
    }
}();
singleton.publicMethod();//弹出1
技术分享

    [应用场景]用于管理组件的application对象

技术分享
var application = function(){
    //私有变量和函数
    var components = new Array();
    //初始化
    components.push(new BaseComponent());
    //公共
    return{
        //返回已注册的数目
        getComponentCount : function(){
            return components.length;
        },
        //注册新组件
        registerComponent : function(component){
            if(typeof component == "object"){
                components.push(component);
            }
        }
    }
}();    
技术分享

 

  【2】【增强模块模式】适合于那些单例必须是某种类型的实例,同时还必须添加某些属性和方法对其加以增强的情况。

技术分享
var singleton = function(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
        alert(1)
        return false;
    }
    //创建对象
    var object = new CustomType();

    //特权方法和属性
    object.publicProperty = true;
    object.publicMethod = function(){
            privateVariable++;
            return privateFunction();
    };
    return object;
}();
技术分享

    [应用场景]用于管理组件的application对象的增强模式

技术分享
var application = function(){
    //私有变量和函数
    var components = new Array();
    //初始化
    components.push(new BaseComponent());
    //创建application的一个局部副本,这个变量实际上是application对象的局部变量版
    var app = new BaseComponent();
    //公共接口
    //返回已注册的数目
    app.getComponentCount = function(){
            return components.length;
    };
    //注册新组件
    app.registerComponent = function(component){
        if(typeof component == "object"){
            components.push(component);
        }
    }
    return app;
}();    
技术分享

 








以上是关于函数中的私有变量和特权方法的主要内容,如果未能解决你的问题,请参考以下文章

Javascript的私有变量和方法共有变量和方法以及特权方法构造器静态共有属性和静态共有方法

两种创建私有变量私有方法的方法

JS 私有变量

javascript--特权方法

对象的私有/公有/静态/特权 属性/方法

深入浅出javascript封装和继承