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