Javascript 公共/私有变量

发布于 2024-12-08 12:55:37 字数 562 浏览 0 评论 0原文

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

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 显示问题

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ˇ宁静的妩媚 2024-12-15 12:55:37

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

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;
夏の忆 2024-12-15 12:55:37

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

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

查看 JSFiddle 上的演示。

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

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

如果这两种方法都不适合您,则必须始终分配这两种方法或始终引用一个方法(如果您想要,则必须是公共方法)公开。

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.

难忘№最初的完美 2024-12-15 12:55:37

我通常使用这种模式,但我还没有看到很多人这样做。
我这样做是为了避免必须以任何特殊方式排序我的方法。如果全部都是公共,那么通常必须确保所调用的方法在方法调用之前声明

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

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;
    }    
}
海未深 2024-12-15 12:55:37

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

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

        }
    }
})();

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

        }
    }
})();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文