开发者

Javascript Public/Private Variables

开发者 https://www.devze.com 2023-04-12 02:57 出处:网络
I have an object containing both public and private variables. The public variables are assigned to the开发者_如何学运维 private variables (I think), however, whenever I modify the private variables w

I have an object containing both public and private variables. The public variables are assigned to the开发者_如何学运维 private variables (I think), however, whenever I modify the private variables with a function, the public variables don't update.

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

Now I know that if I change the line in changeVar to this.a = 2; it works but then it doesn't update the private variable. I want to update both the private and public variables at the same time. Is this possible?

JsFiddle showing problem


When you set the a key in the object you're returning, that's making a copy of the 'private' a variable.

You can either use a getter function:

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

Or you can use Javascript's built-in accessor functionality:

obj = {
    //Public vars/methods
    changeVar: function () {
        a = 2;
    }
};
Object.defineProperty(obj, "a", { get: function() { return a; } });
return obj;


Yes, if you're using a newer browser:

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

See a demo on JSFiddle.

There's also a more compatible method, but it requires changing the code that uses it:

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

If neither of these methods work for you, you'll have to either always assign both or always reference one (which must be the public one if you intend it to be public.


I normally use this pattern, that I haven't seen many do. I do this to avoid having to order my methods in any special way. If all is public, then one normally has to ensure that the methods called, are declared before the method call

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


Others have given you the get answer, but your question seemed more about setting the value.

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

That is a one-of assignment to a, which is local to the anonymous function.

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

That is also a one-of assignment of the value of a to an a property of the object that will be referenced by foo. Subsequent changes to the variable a will not affect the value of this property.

        changeVar: function () {
            a = 2;

Here, a will resolve to a reference to the "outer" a, so it will change the value of the variable but it won't change the value of foo.a. If you know it will always be called as a method of foo, they you can instead write:

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

so that it resolves a as a property of foo, not the scope chain (and hence variable a).

        }
    }
})();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号