Jak poprawnie skonfigurować przestrzeń nazw i klasy JavaScript?

Wydaje się, że istnieje tak wiele sposobów, aby skonfigurować aplikację JavaScript, więc jest mylące, który z nich jest poprawny lub najlepszy. Czy istnieje jakaś różnica w stosunku do poniższych technik lub lepszy sposób na to?

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

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

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

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

Inny sposób:

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();

Pierwsza technika wydaje się bardziej jak Klasa. Pochodzę z tła po stronie serwera, jeśli to robi różnicę. Druga technika wydaje się bardziej zbędna i trochę niezręczna, ale widzę, że to też często używane. Czy ktoś może pomóc rzucić trochę światła i doradzić najlepszy sposób, aby przejść do przodu? Chcę stworzyć aplikację z wieloma klasami rozmawiającymi ze sobą.

Author: Neal, 2012-07-25

5 answers

Nie rób żadnej z tych rzeczy.

Make a 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();

Jeden z varami statycznymi:

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();

Z "konstruktorem" (wszystkie przykłady mają "konstruktor", ten ma tylko parametry do pracy):

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);

Z wszystkich powyższych można można zrobić :

MyNamespace.MyClass.someFunction();

Ale ty nie możesz zrobić (z zewnątrz):

MyNamespace.MyClass.privateFn(); //ERROR!
 59
Author: Neal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-25 14:26:40

Pierwszy przykład to po prostu literał obiektu - nie może być utworzony i nie ma prywatnych członków. Drugi przykład ma niepoprawną składnię (var someProperty: 5 powinna być var someProperty = 5), ale używa zamknięcia do hermetyzacji wewnętrznego stanu prywatnego wewnątrz funkcji anonimowej.

Drugie podejście wygląda lepiej dla enkapsulacji prywatnych członków, ale może być bardziej "zorientowane obiektowo", czyniąc z niej instancjonalną klasę:

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

Wtedy możesz utworzyć instancję to ze słowem kluczowym "Nowy":

var aClass = new MyNamespace.MyClass();
aClass.init(...);
 6
Author: chrisf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-25 14:09:19

Używam następującej składni dla klas instancyjnych z przestrzenią nazw

 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/

 4
Author: Razan Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-10 00:05:31

Dlaczego nigdy nie należy używać

 return { methodName : methodDelegate}

Jak w drugim przykładzie:

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

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

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

MyNamespace.MyClass.init();

Kiedy używasz przestrzeni nazw, musisz myśleć o niej jak o deklaracji, a nie o instancji.

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);

I nie metter ile moduł anti-patter był popularny. Declaration daje możliwość używania tego samego kodu z różnymi instancjami w oczekiwany dla innych programistów sposób . Zwiększa się jakość kodu i prostota jego odczytu. Celem każdego programisty jest napisanie prostego kodu, który będzie Czytaj, nie krótszy ani D. R. Y. - ale prosty do odczytania i opanowania przez innego dewelopera. To zmniejsza liczbę błędów w pierwszej kolejności. c) S. McConnell

 2
Author: Artem G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-30 21:56:29

Jak połączyć przestrzeń nazw i deklarację klasy:

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);
    }
};

Dostęp do twojej wartości:

console.log(ns.my_value);

Teraz, dla klasy i funkcji: jeśli użyjesz new, słowo {[5] } wewnątrz funkcji wskaże jej konstruktor. Jeśli nie używasz new, this wskaże przestrzeń nazw. Więc

Użycie klasy:

var obj = new ns.MyClass();

Użycie funkcji:

ns.myFunction();

Jeśli zbudujesz obiekt bez new, this wskaże przestrzeń nazw, więc przestrzeń nazw będzie być "zniszczone", ponieważ MyClass.class_property i MyClass.class_method zostaną do niego dodane.

 0
Author: marirena,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-28 14:25:40