Подтвердить что ты не робот

Как правильно настроить пространство имен и классы JavaScript?

Кажется, существует так много способов настроить приложение 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();

Первый метод больше похож на класс. Я исхожу из серверного фона, если это имеет значение. Второй метод кажется более избыточным и немного неудобным, но я вижу, что это слишком много. Может кто-то, пожалуйста, поможет пролить свет и посоветовать лучший способ двигаться вперед? Я хочу создать приложение с большим количеством классов, разговаривающих друг с другом.

4b9b3361

Ответ 1

Не делайте ни одной из этих вещей.

Сделайте 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();

Один со статическими vars:

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!

Ответ 2

Первый пример - это просто литерал объекта - он не может быть создан и не имеет частных членов. Второй пример имеет некорректный синтаксис (var someProperty: 5 должен быть var someProperty = 5), но использует закрытие для инкапсуляции внутреннего частного состояния в самозапускающуюся анонимную функцию.

Второй подход выглядит лучше для инкапсуляции частных членов, но его можно сделать более "Объектно-ориентированным", сделав его понятным классом:

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

Затем вы можете создать экземпляр с помощью ключевого слова 'new':

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

Ответ 3

Я использую следующий синтаксис для реализуемых классов с пространством имен

 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

Почему вы никогда не должны использовать

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

И не важно, насколько популярна система Anti-Patter. Декларация дает вам возможность использовать один и тот же код с разными экземплярами ожидаемым способом для других разработчиков. Качество кода и простота его чтения увеличивается. Цель любого разработчика - написать простой код для чтения, а не более короткий или D.R.Y. - но просты для чтения и понимания другим разработчиком. Это уменьшает количество ошибок в первую очередь. (c) С. Макконнелл

Ответ 5

Как объединить пространство имен и объявление класса:

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 внутри функции укажет на конструктор. Если вы не используете new, this укажет на пространство имен. Таким образом,

Использование класса:

var obj = new ns.MyClass();

Использование функции:

ns.myFunction();

Если вы создадите объект без new, this укажет на пространство имен, поэтому пространство имен будет "уничтожено", потому что к нему будут добавлены MyClass.class_property и MyClass.class_method.