Javascript 公共/私有变量

Posted

技术标签:

【中文标题】Javascript 公共/私有变量【英文标题】:Javascript Public/Private Variables 【发布时间】:2011-12-03 10:28:12 【问题描述】:

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

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

【问题讨论】:

这种方法怎么样? marcelorjava.wordpress.com/2014/06/07/… 【参考方案1】:

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

【讨论】:

为什么a = 1; b = a:a; b.a++不会影响a,而a=[]; b= a:a; b.a.push(1)会影响a? @lostyzd ***.com/questions/6605640/…【参考方案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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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)。

        
    
)();

【讨论】:

我在 OP 中声明 this.a 引用公共 'a' 而不是私有 'a' 但我想同时更改两者,这是不正确的吗?我修改了已接受答案的第一个解决方案,使其也成为二传手。 a: function(value) if(arguments.length > 0) a = value; else return a; 是的,您可以同时更改两者。访问一个作为对象属性,另一个作为范围链上的变量,例如changeValue: function(value)this.a = value; a = value;. 这就是你问的,不是吗?你不能用一个表达式来改变两者,它需要两个表达式。 通过 getter/setter 将它们合并在一起似乎更好。

以上是关于Javascript 公共/私有变量的主要内容,如果未能解决你的问题,请参考以下文章

javascript私有函数访问公共变量

我可以在公共方法中声明私有变量吗?

公共静态变量和私有静态变量之间的区别

不是公共或私有的变量-Java

子类真的继承私有成员变量吗?

如何在公共方法中创建私有变量