簡體   English   中英

如何正確設置JavaScript命名空間和類?

[英]How to set up JavaScript namespace and classes properly?

似乎有很多方法來設置JavaScript應用程序,因此令人困惑的是哪一個是正確的還是最好的。 以下技術或更好的方法有什么不同嗎?

MyNamespace.MyClass = {
    someProperty: 5,
    anotherProperty: false,

    init: function () {
        //do initialization
    },

    someFunction: function () {
        //do something
    }
};

$(function () {
    MyNamespace.MyClass.init();
});

其他方式:

MyNamespace.MyClass = (function () {
    var someProperty = 5;
    var anotherProperty = false;

    var init = function () {
        //do something
    };

    var someFunction = function () {
        //do something
    };

    return {
        someProperty: someProperty
        anotherProperty: anotherProperty
        init: init
        someFunction: someFunction
    };
}());

MyNamespace.MyClass.init();

第一種技術感覺更像是一門課。 如果這有所不同,我來自服務器端背景。 第二種技術似乎更冗余,有點尷尬,但我看到這也使用了很多。 有人可以幫助解決一些問題並建議前進的最佳方式嗎? 我想創建一個有很多類相互交流的應用程序。

不做這些事情。

制作一個javascript“class”:

var MyClass = function () {

    var privateVar; //private
    var privateFn = function(){}; //private 

    this.someProperty = 5;  //public
    this.anotherProperty = false;  //public
    this.someFunction = function () {  //public
        //do something
    };

};

MyNamespace.MyClass = new MyClass();

一個有靜態變量:

var MyClass = (function(){

    var static_var; //static private var

    var MyClass = function () {

        var privateVar; //private
        var privateFn = function(){}; //private 

        this.someProperty = 5;  //public
        this.anotherProperty = false;  //public
        this.someFunction = function () {  //public
            //do something
        };
    };

    return MyClass;

})();

MyNamespace.MyClass = new MyClass();

使用“構造函數”(所有示例都有一個“構造函數”,這個只有參數可以使用):

var MyClass = function (a, b c) {

    //DO SOMETHING WITH a, b, c <--

    var privateVar; //private
    var privateFn = function(){}; //private 

    this.someProperty = 5;  //public
    this.anotherProperty = false;  //public
    this.someFunction = function () {  //public
        //do something
    };

};

MyNamespace.MyClass = new MyClass(1, 3, 4);

有了上述所有功能,您可以

MyNamespace.MyClass.someFunction();

但你不能 (從外面):

MyNamespace.MyClass.privateFn(); //ERROR!

第一個示例只是一個Object文字 - 它無法實例化,也沒有私有成員。 第二個示例有一些不正確的語法( var someProperty: 5應該是var someProperty = 5 )但是使用閉包來封裝內部私有狀態在自調用匿名函數中。

第二種方法看起來更適合封裝私有成員,但可以通過使其成為可實例化的類來使其更加“面向對象”:

MyNamespace.MyClass = function() { ... };
MyNamespace.MyClass.prototype.someProperty = 'foo';

然后,您可以使用'new'關鍵字對其進行實例化:

var aClass = new MyNamespace.MyClass();
aClass.init(...);

我將以下語法用於帶有命名空間的可實例化類

 var MYNamespace = MYNamespace|| {};

 MYNamespace.MyFirstClass = function (val) {
        this.value = val;
        this.getValue = function(){
                          return this.value;
                       };
    }

var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());

jsfiddle: http//jsfiddle.net/rpaul/4dngxwb3/1/

為什么你永遠不應該使用

 return { methodName : methodDelegate}

像在第二個例子中:

MyNamespace.MyClass = (function () {
    var someProperty = 5;

    var init = function () {
        //do something
    };

    return {
        someProperty: someProperty
        someFunction: someFunction
    };
}());

MyNamespace.MyClass.init();

當您使用命名空間時,您必須將其視為關於聲明而不是實例。

MyNamespace = {};
MyNamespace.sub = {};
MyNamespace.anotherSub = {};
MyNamespace.sub.MyClass = (function () {

    var static_var; //static private var

    var MyClass2 = function () {

        var privateVar; //private
        var privateFn = function () { }; //private 

        this.someProperty = 5;  //public
        this.anotherProperty = false;  //public
        this.someFunction = function () {  //public
            //do something
        };
    };

    return MyClass2;

})();
debugger;

var c1 = new MyNamespace.sub.MyClass();
c1.someProperty = 1; // creates 5->1.

var c2 = new MyNamespace.sub.MyClass();
c2.someProperty = 2;  // creates 5->2. c1 is still 1



debugger;
var myClass = function () {
    var someProperty = 5;
    var anotherProperty = false;

    var init = function () {
        //do something
    };

    var someFunction = function () {
        //do something
    };

    return {
        someProperty: someProperty,
        anotherProperty: anotherProperty,
        init: init,
        someFunction: someFunction
    };
};


MyNamespace.MyClass = myClass();
var c2 = MyNamespace.MyClass;
// how  are planning to create one more object, while it's a reference? copy      //the whole one?

c2.someProperty = 2; // changes 5 -> 2
var c3 = MyNamespace.MyClass.init(); // create 2 instead of 5

c3.someProperty = 3;    // changes c3 and c3 from 2 to 3.
console.log(c2.someProperty + c3.someProperty);

而且沒有多少模塊反模式受歡迎。 聲明使您能夠以預期的方式為其他開發人員使用相同的代碼和不同的實例。 代碼質量和閱讀簡單性增加。 任何開發人員的目標都是編寫一個簡單的代碼來讀取,而不是簡短或干燥 - 但很容易被其他開發人員閱讀和理解。 這首先減少了bug的數量。 (c)S. McConnell

如何組合命名空間和類聲明:

var ns = { // your namespace
    my_value: 1, // a value inside the namespace to avoid polluting
    MyClass: function() { // a class inside the namespace
        this.class_property: 12,
        this.class_method: function() {
            console.log("My property: " + this.class_property);
        }
    },
    myFunction: function() { // a function inside a namespace
        console.log("I can access namepsace value if you don't use 'new': " + this.my_value);
    }
};

獲取您的價值:

console.log(ns.my_value);

現在,對於類和函數:如果您使用new ,這個詞this里面的功能將指向它的構造。 如果不使用newthis將指向命名空間。 所以,

使用班級:

var obj = new ns.MyClass();

使用功能:

ns.myFunction();

如果你構造沒有new的對象, this將指向命名空間,因此命名空間將被“銷毀”,因為MyClass.class_propertyMyClass.class_method將被添加到它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM