Javascript: общий геттер/сеттер для выявления шаблона модуля

В основном то, что я пытаюсь сделать, это написать повторно используемый геттер/сеттер для предоставления переменных с использованием шаблона модуля.

// the getter/setter
function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        publicVariable: pub(publicVariable),
        test: test
    }
})();

Желаемый результат следующий:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 1

Но вместо этого я получаю:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 0

Я предполагаю, что это связано с тем, что следующая строка передает текущее значение publicVariable в pub, поэтому создается только замыкание внутри pub, и нет ссылки на саму переменную.

publicVariable: pub(publicVariable),    // same as "pub(0)"

Я знаю, что в javascript нет возможности пройти по ссылке. Итак, как еще я могу выполнить то, что я пытаюсь сделать? Меня не волнует, вызывается ли реквизит функцией или свойством.

т. е. любой из следующих вариантов подходит

module.publicVariable = "new value";
module.publicVariable("new value");

Я просто устал писать:

function prop1f (value) {  return (arguments.length ? prop1 = value : prop1); }
function prop2f (value) {  return (arguments.length ? prop2 = value : prop2); }
function prop3f (value) {  return (arguments.length ? prop3 = value : prop3); }

return {
    prop1: prop1f,
    prop2: prop2f,
    prop3: prop3f
}

так как это становится неуправляемым быстро в больших проектах с большим количеством доступных пользователю свойств.


person thedarklord47    schedule 19.07.2016    source источник
comment
Если эти сеттеры/геттеры не делают ничего особенного, вам вообще не следует их использовать. Просто используйте стандартное свойство!   -  person Bergi    schedule 20.07.2016
comment
как свойства становятся общедоступными в шаблоне модуля?   -  person thedarklord47    schedule 20.07.2016
comment
Вы можете просто создать саму переменную внутри pub, чтобы ваш собственный код использовал геттер/сеттер вместо var publicVariable напрямую.   -  person Bergi    schedule 20.07.2016
comment
Просто используйте var module = {publicVariable: 0, test () { return this.publicVariable; }};   -  person Bergi    schedule 20.07.2016
comment
надеялся использовать шаблон модуля, чтобы у меня были частные методы и переменные, а также общедоступные. Я также надеялся не писать везде this   -  person thedarklord47    schedule 20.07.2016
comment
Вы по-прежнему можете обернуть объект в IEFE, просто в этом примере это не нужно. Вы можете избежать this с помощью статической переменной, но вы не можете избежать ссылок на свойства, если вам нужны общедоступные свойства без громоздких методов доступа.   -  person Bergi    schedule 20.07.2016
comment
Не уверен, отвечает ли (показывающий) шаблон модуля, общедоступные переменные и оператор возврата на ваш вопрос, если да, я закрою как дубликат   -  person Bergi    schedule 20.07.2016
comment
Поскольку это js, а не java или c#, вам следует пересмотреть шаблон приватной переменной с общедоступным геттером и сеттером. В js проще всего использовать общедоступную переменную. Еще одна вещь, которую вы должны пересмотреть, это ваше избегание этого. На мой взгляд, это часто предпочтительнее закрытия. Злоупотребление замыканием шаблона раскрытия модулей делает его плохо работающим в отношении переопределения и наследования.   -  person I-Lin Kuo    schedule 20.07.2016


Ответы (1)


Проблема в том, что этот код:

function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}

может отлично работать как геттер, но как сеттер: если вы измените сам параметр (переменную), это не повлияет на элемент, который был передан в параметр. Но если вы измените внутренности параметра, это будет распространяться обратно.

Вместо этого вы можете использовать javascript геттеры/сеттеры:

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        set publicVariable (value) {
            publicVariable = value;
        },
        get publicVariable () {
            return publicVariable;
        },
        test: test
    }
})();

module.publicVariable = 'New value';
console.log(module.publicVariable);

Демонстрация:

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
    	set publicVariable (value) {
            publicVariable = value;
        },
        get publicVariable () {
        	return publicVariable;
        },
        test: test
    }
})();

module.publicVariable = 'New Value';
console.log(module.publicVariable);
console.log(module.test());

Другой общий вариант:

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        //This function can access `publicVariable` !
        publicVariable: function(value) {
            return (arguments.length ? publicVariable = value : publicVariable);
        },
        test: test
    }

})();

module.publicVariable('new Value');
console.log(module.publicVariable());

Демонстрация:

var module = (function () {

    var publicVariable = 0;
    
    function test () {
        return publicVariable;
    }

    return {
        //This function can access `publicVariable` !
    	publicVariable: function(value) {
        	return (arguments.length ? publicVariable = value : publicVariable);
        },
        test: test
    }
    
})();

module.publicVariable('new Value');
console.log(module.publicVariable());

person Ismail RBOUH    schedule 19.07.2016
comment
Вы можете показать пример того, как вы можете использовать геттеры и сеттеры с раскрывающимся шаблоном модуля. - person Heretic Monkey; 20.07.2016
comment
да, я знаю, где проблема в моем коде. Я не могу использовать геттеры/сеттеры, так как это код на стороне клиента и не всегда поддерживается - person thedarklord47; 20.07.2016
comment
@thedarklord47 геттеры/сеттеры - это IE9+! - person Ismail RBOUH; 20.07.2016
comment
в любом случае, чтобы сделать это общим? это было первоначальной целью вопроса. - person thedarklord47; 20.07.2016
comment
@thedarklord47, пожалуйста, ознакомьтесь с ответом. Поверьте мне! это лучшее, что ты можешь сделать! если вы не назначите переменные this, чтобы вы могли получить доступ к переменной переменной this['varname']! если вы понимаете, что я имею в виду! - person Ismail RBOUH; 20.07.2016
comment
Я не был против. После взвешивания различных вариантов я собираюсь пойти с геттерами/сеттерами в вашем ответе. Спасибо! - person thedarklord47; 20.07.2016