Javascript Public / Private Variables - PullRequest
       21

Javascript Public / Private Variables

3 голосов
/ 08 октября 2011

У меня есть объект, содержащий как публичные, так и приватные переменные.Публичные переменные назначаются частным переменным (я думаю), однако всякий раз, когда я изменяю закрытые переменные с помощью функции, публичные переменные не обновляются.

var foo = (function() {
    //Private vars
    var a = 1;

    return {
        //Public vars/methods
        a: a,
        changeVar: function () {
            a = 2;
        }
    }
})();
alert(foo.a);  //result: 1
foo.changeVar();
alert(foo.a);  //result: 1, I want it to be 2 though

Теперь я знаю, что если я изменюстрока в changeVar в this.a = 2; работает, но затем не обновляет приватную переменную.Я хочу обновить как приватные, так и публичные переменные одновременно.Возможно ли это?

JsFiddle с проблемой

Ответы [ 4 ]

8 голосов
/ 08 октября 2011

Когда вы устанавливаете ключ a в возвращаемом объекте, это создает копию переменной 'private' a.

Вы можете использовать функцию получения:

return {
    //Public vars/methods
    a: function() { return a; },
    changeVar: function () {
        a = 2;
    }
};

Или вы можете использовать встроенную функцию доступа Javascript:

obj = {
    //Public vars/methods
    changeVar: function () {
        a = 2;
    }
};
Object.defineProperty(obj, "a", { get: function() { return a; } });
return obj;
2 голосов
/ 08 октября 2011

Да, если вы используете более новый браузер:

var foo = (function() {
    var a = 1;
    return {
        get a() { return a; },
        changeVar: function () {
            a = 2;
        }
    }
})();

См. Демонстрацию по JSFiddle.

Также естьболее совместимый метод, но он требует изменения кода, который его использует:

var foo = (function() {
    var a = 1;
    return {
        getA: function() { return a; },
        changeVar: function () {
            a = 2;
        }
    }
})();
alert(foo.getA()); // rather than foo.a

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

1 голос
/ 15 декабря 2012

Я обычно использую этот шаблон, который я не видел, как многие делают. Я делаю это, чтобы избегать необходимости заказа моих методов любым специальным способом. Если все public , то один обычно должен гарантировать, что вызываемые методы объявлены до вызова метода

var person = new Person("Mohamed", "Seifeddine");
person.getFullname();
person.getFirstname();
person.getLastname();           

function Person(firstname, lastname) {
    var firstname, lastname;

    (function constructor(){
        setFirstname(firstname);
        setLastname(lastname)
    })();

    this.getFullname = getFullname;   // Makes getFullName() public 
    function getFullname() {
        // Will allow you to order method in whatever order you want. 
        // If we where to have it as just this.getFullname = function () {...} and same for firstname 
        // as it is normally done, then this.getFirstname would have to be placed before this method. 
        // A common pain in the ass, that you cannot order methods as you want!    
        return getFirstname() + ", " + getLastname();   
    }               

    this.getFirstname = getFirstname;
    function getFirstname() {
        return firstname;
    }

    function setFirstname(name){
        firstname = name;
    }

    this.getLastname = getLastname;
    function getLastname() {
        return lastname;
    }
    function setLastname(name) {
        lastname = name;
    }    
}
0 голосов
/ 08 октября 2011

Другие дали вам ответ get, но ваш вопрос казался больше об установке значения.

var foo = (function() {
    //Private vars
    var a = 1;

Это одно из присвоения a , которое является локальным дляанонимная функция.

    return {
        //Public vars/methods
        a: a,

Это также однократное присвоение значения a свойству a объекта, на который будет ссылаться Foo .Последующие изменения в переменной a не повлияют на значение этого свойства.

        changeVar: function () {
            a = 2;

Здесь a разрешит ссылку на "внешний" a , поэтому он изменит значение переменной, но не изменит значение foo.a .Если вы знаете, что он всегда будет вызываться как метод foo , вместо этого вы можете написать:

        changeVar: function () {
            this.a = 2;

, чтобы он разрешил a как свойство foo , а не цепочка областей действия (и, следовательно, переменная a ).

        }
    }
})();
...