1

所以在我总是使用这种封装我的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 很陌生,我想知道哪种方式声明类/封装我的代码是首选方式,为什么?

4

2 回答 2

2

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

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

那有什么区别呢?

主要有两个方面:

  • 您的第一个模式确实立即调用该函数并使用公共方法初始化您的对象 - 创建一个“单例”。这称为显示模块模式。第二个只定义(创建)一个可以多次使用的函数,以实例化许多具有相似形状的对象。此处的调用(带有())在您的 dom-ready 处理程序中。
  • 虽然第一种模式确实产生了一个简单、普通的对象,但第二种模式是一个构造函数。当使用new关键字调用时,它将创建一个从对象继承属性的Cname.prototype对象。您尚未在其上创建任何属性,因此除了constructor属性:之外它是空的cname.constructor == Object.getPrototypOf(cname).constructor == Cname.prototype.constructor == Cname。你很快就会在你的课程中学习这个原型继承:-)
于 2013-09-09T23:02:11.437 回答
1

Bergi 的回答总结得很好,但我只是想补充一点,可以将两种模式结合起来而没有任何一个缺点:在 javascript 中选择 OOP 模式。您老师的示例的好处是允许完全独立的实例Cname(例如,如果您继续添加var cname2 = new Cname('test3', 'test4');test1则内部不可用,内部cname2也不test3可用cname),但缺点是将函数添加到内存中(Getvariable1) 对于这些独立实例中的每一个。通过在原型上声明 getter 函数(如链接示例中所示),这只会将一个函数添加到内存中,但在所有这些实例上都可用(尽管与您的老师的示例一样,如果您确定它会增加太多开销您只需要一个实例)。

顺便说一句,对于您的示例,即使在全局范围内,使用 声明也是一个好主意,因为“严格模式”不允许省略声明,这是现代 JavaScript 引擎中添加的一项更新的功能,以允许更快和更严格的Classtype编码var(在严格模式下要求 'var' 可能是为了避免 JavaScript 太容易创建意外全局变量的能力)。

于 2013-09-09T23:12:46.083 回答