封装Javascript和定义私有变量/方法的首选方法?

时间:2013-09-09 22:44:39

标签: javascript

所以在我总是使用这种封装我的Javascript的方法之前:

Classtype = (function (){
//private members

    var variable1;
    var variable2;

//

//public methods
    return {
        SetVariable1: function(pvariable){
        variable1 = pvariable;
        },

        GetVariable1: function(){
        return variable1;
        }

    };    
})();

$(document).ready(function(){

    Classtype.SetVariable1('var');
    var t = Classtype.GetVariable1();
    alert(t);
});

但今天在我的Javascript课程中,老师教我们以下内容:

function Cname(pvariable1, pvariable2)
{
//private members//
var variable1 = pvariable1;
var variable2 = pvariable2;

//Getter

this.Getvariable1=function() {
return variable1;
 }   
}

$(document).ready(function(){
var cname = new Cname('test1', 'test2');
var r = cname.Getvariable1();
alert(r);        
});

由于我对Javascript很陌生,我想知道哪种方式声明类/封装我的代码是首选的方式和原因?

2 个答案:

答案 0 :(得分:2)

  

定义私有变量/方法的首选方法?

只有一种方式,在两个片段中都是一样的。您有一个函数作用域,其中声明了变量,并且在调用函数时,它们的值已设置。在该范围内创建的任何函数都可以访问它们,即使这些函数是从外部调用的(当它们从作用域导出时,例如通过将它们返回到对象上)。

  

那有什么不同呢?

主要有两个方面:

  • 您的第一个模式执行immediately invoke the function并使用公共方法初始化您的对象 - 创建“单例”。这称为揭示模块模式。第二个只定义(创建)可以多次使用的函数,以实例化具有相似形状的许多对象。这里的调用(())位于你的dom-ready处理程序中。
  • 虽然第一个模式确实产生了一个简单的普通对象,但第二个模式是一个构造函数函数。使用new keyword调用时,它将创建一个从Cname.prototype对象执行继承属性的对象。您尚未创建任何属性,因此除了constructor属性cname.constructor == Object.getPrototypOf(cname).constructor == Cname.prototype.constructor == Cname之外它都是空的。您很快就会在课程中进入原型继承: - )

答案 1 :(得分:1)

Bergi的答案总结得很好,但我只是想补充说,可以将这两种模式结合起来而没有任何一个缺点:Choosing an OOP pattern in javascript。您的教师示例的好处是允许完全独立的Cname实例(例如,如果您继续添加var cname2 = new Cname('test3', 'test4');,则test1cname2将无法使用test3 {1}}在cname}内不可用,但它的缺点是为每个独立实例的内存(Getvariable1)添加一个函数。通过在原型上声明getter函数(如在链接示例中),这将只在内存中添加一个函数,但在所有这些实例上都可用(尽管如同您的老师的例子一样,如果您确定的话,它会增加太多开销你只需要一个实例。

对于你的例子,顺便说一句,最好用Classtype声明var,即使在全局范围内,因为“严格模式”不允许省略声明,这是一个更新的功能被添加到现代JavaScript引擎中以允许更快和更紧凑的编码(在严格模式下需要'var'可能是为了避免JavaScript过于简单的创建偶然全局变量的能力)。

相关问题