Javascript公共/私人变量

时间:2011-10-08 04:32:40

标签: javascript variables scope private public

我有一个包含公共和私有变量的对象。公共变量被分配给私有变量(我认为),但是,每当我用函数修改私有变量时,公共变量都不会更新。

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 showing problem

4 个答案:

答案 0 :(得分:7)

当您在要返回的对象中设置a键时,会对“私有”a变量进行复制

您可以使用getter函数:

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;

答案 1 :(得分:2)

是的,如果您使用的是较新的浏览器:

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

<强> See a demo on JSFiddle.

还有一个更兼容的方法,但它需要更改使用它的代码:

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

如果这些方法都不适合你,你必须要么总是分配两个或总是引用一个(如果你打算将它公开,那么它必须是公共的。

答案 2 :(得分:1)

我通常使用这种模式,我没见过很多。 我这样做是为了避免以任何特殊的方式订购我的方法。如果所有公开,那么一个通常必须确保所谓的方法方法调用之前声明

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

答案 3 :(得分:0)

其他人给了你答案,但你的问题似乎更多的是关于设定价值。

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

这是 a 的一项任务,它是匿名函数的本地。

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

这也是将 a 的值分配给 foo 引用的对象的 a 属性之一。对变量 a 的后续更改不会影响此属性的值。

        changeVar: function () {
            a = 2;

在这里, a 将解析为对“外部” a 的引用,因此它将更改变量的值,但不会更改 foo.a 。如果您知道它总是被称为 foo 的方法,那么您可以改为:

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

因此它将 a 解析为 foo 的属性,而不是作用域链(因此变量 a )。

        }
    }
})();