Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript公共/私有变量_Javascript_Variables_Scope_Private_Public - Fatal编程技术网

Javascript公共/私有变量

Javascript公共/私有变量,javascript,variables,scope,private,public,Javascript,Variables,Scope,Private,Public,我有一个包含公共和私有变量的对象。公共变量被分配给私有变量(我想),但是,每当我用函数修改私有变量时,公共变量不会更新 var foo = (function() { //Private vars var a = 1; return { //Public vars/methods a: a, changeVar: function () { a = 2; } } })();

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

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它工作,但不更新私有变量。我想同时更新私有变量和公共变量。这可能吗


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

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

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

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

如果这两种方法都不适用于您,则您必须始终分配这两种方法或始终引用其中一种方法(如果您希望它是公共的,则必须是公共方法)。

当您在返回的对象中设置
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;

其他人已经给了你答案,但是你的问题似乎更多的是关于设置值

var foo = (function() {
    //Private vars
    var a = 1;
这是对a的赋值之一,它是匿名函数的本地赋值

    return {
        //Public vars/methods
        a: a,
这也是将a的值赋值给foo将引用的对象的属性之一。对变量a的后续更改不会影响此属性的值

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

        changeVar: function () {
            this.a = 2;
因此,它将a解析为foo的属性,而不是范围链(以及变量a)


我通常使用这种模式,我没有见过很多人这样做。 我这样做是为了避免不得不以任何特殊的方式对我的方法进行排序。如果所有方法都是公共的,那么一个正常的必须确保在方法调用之前声明调用的方法

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

为什么
a=1;b={a:a};b.a++
不会影响a,但
a=[];b={a:a};b.a.push(1)
effects a?@lostyzd我在OP中说,
this.a
引用了公共的“a”而不是私有的“a”,但我想同时更改这两个,这是否不正确?我修改了接受答案的第一个解,使其也成为setter。
a:function(value){if(arguments.length>0)a=value;否则返回a;
Yes,您可以同时更改这两个属性。访问一个作为对象属性,另一个作为作用域链上的变量,例如
changeValue:function(value){this.a=value;a=value;}
。这就是你要问的,不是吗?你不能用一个表达式来同时更改这两个表达式,它需要两个表达式。通过getter/setter将它们合并在一起似乎更好。这种方法怎么样?
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;
    }    
}