Javascript 公共/私有变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7694840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 00:59:04  来源:igfitidea点击:

Javascript Public/Private Variables

javascriptvariablesscopeprivatepublic

提问by Michael

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?

现在我知道,如果我将 changeVar 中的行更改为this.a = 2;有效,但它不会更新私有变量。我想同时更新私有变量和公共变量。这可能吗?

JsFiddle showing problem

JsFiddle 显示问题

回答by anonymous coward

When you set the akey in the object you're returning, that's making a copyof the 'private' avariable.

当您a在要返回的对象中设置键时,即创建了“私有”变量的副本a

You can either use a getter function:

您可以使用 getter 函数:

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

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

或者您可以使用 Javascript 的内置访问器功能:

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

回答by icktoofay

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.

请参阅 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.

如果这两种方法都不适合您,则您必须始终分配两者或始终引用一个(如果您打算将其公开,则必须是公开的。

回答by mmm

I normally use this pattern, that I haven't seen many do. I do this to avoidhaving to ordermy methods in any specialway. If all is public, then one normallyhas to ensure that the methods called, are declared beforethe method call

我通常使用这种模式,我没有看到很多人这样做。我这样做是为了避免以任何特殊方式订购我的方法。如果 all 是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;
    }    
}

回答by RobG

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 ato an aproperty of the object that will be referenced by foo. Subsequent changes to the variable awill not affect the value of this property.

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

        changeVar: function () {
            a = 2;

Here, awill 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:

在这里,a将解析为对“外部” a的引用,因此它将更改变量的值但不会更改foo.a的值。如果您知道它将始终作为foo的方法调用,则您可以改为编写:

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

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

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

        }
    }
})();