Javascript对象:如何创建包含封装的工作对象?
我想使用面向对象的Javascript,但我的“对象”的行为并不像我期望的那样 这是我的目标:Javascript对象:如何创建包含封装的工作对象?,javascript,object,constructor,encapsulation,Javascript,Object,Constructor,Encapsulation,我想使用面向对象的Javascript,但我的“对象”的行为并不像我期望的那样 这是我的目标: var Test = function(a){ var variable = a; this.getA = function(){ return this.variable; } this.setA = function(a){ this.variable = a; } } 现在我运行以下代码: var a = new Te
var Test = function(a){
var variable = a;
this.getA = function(){
return this.variable;
}
this.setA = function(a){
this.variable = a;
}
}
现在我运行以下代码:
var a = new Test("foo");
var b = new Test("bar");
alert(a.getA()); //undefined, but "foo" expected
alert(a.getA() == b.getA()); //true, but false expected
alert(a.variable); //undefined, as expected
a.variable = "whatever";
alert(a.getA()); //"whatever", but undefined expected
alert(a.variable); //"whatever", but undefined expected
a.setA("somewhere");
alert(a.getA()); //"somewhere", as expected
alert(a.variable); //"somewhere", but undefined expected
是否有人知道如何创建一个功能正常的对象,而不需要在开始时调用“setA(a)”,并且对象封装不允许使用a.variable=“whatever” 如果要封装
a
的值,则不需要使用this.variable
来访问该值,只需将this.variable
更改为variable
即可解决问题
变量具有功能范围,因此var variable
定义了一个变量,该变量不仅适用于Test
,也适用于setA
和getA
:
var Test = function(a){
var variable = a;
this.getA = function(){
//you want to access the variable,
//not the property on the instance
return variable;
}
this.setA = function(a){
variable = a;
}
}
如果要封装
a
的值,则不需要使用this.variable
来访问该值,只需将this.variable
更改为variable
即可解决问题
变量具有功能范围,因此var variable
定义了一个变量,该变量不仅适用于Test
,也适用于setA
和getA
:
var Test = function(a){
var variable = a;
this.getA = function(){
//you want to access the variable,
//not the property on the instance
return variable;
}
this.setA = function(a){
variable = a;
}
}
JS中引用的任何
此
都将公开访问
但是,由于闭包的概念,只需在函数中声明变量(或函数),就可以拥有完全私有的状态
此外,除非您希望通过编码获得原型,否则您甚至不需要新的
,也不需要这个
例如:
var makePerson = function (secret) {
var is_alive = true,
sayName = function () {
if (!is_alive) { return; }
console.log("My name is " + secret.name + ".");
},
sayAge = function () {
if (!is_alive) { return; }
console.log("My age is " + secret.age + ".");
},
haveBirthday = function () {
if (!is_alive) { return; }
secret.name += 1;
console.log("I'm " + secret.name +
", and today I turned " + secret.age + ".");
},
die = function () {
is_alive = false;
console.log(secret.name + " died today;" +
" they were " + secret.age + " year" +
(secret.age > 1 ? "s" : "") + " old." );
},
public_interface = { sayName : sayName,
sayAge : sayAge,
haveBirthday : haveBirthday,
die : die };
return public_interface;
};
var bob = makePerson({ name : "Bob", age : 32 });
任何人都不能从外面触摸secret.name
,secret.age
或是活着的
bob.name; // undefined
bob.is_alive = false; // Doesn't matter -- the code isn't relying on a public property.
bob.sayAge(); // "My age is 32"
bob.haveBirthday(); // "I'm Bob, and today I turned 33"
bob.die(); // "Bob died today; they were 33 years old"
更妙的是,JS允许您随时更改任务,因此您可能会担心以下情况:
// person overwriting the function
bob.haveBirthday = function () { is_alive = false; };
…但绝对没有理由害怕有人这样做,因为他们无法访问这些内部属性
bob.haveBirthday(); // window.is_alive = false;
bob.sayAge(); "My age is 33";
同样,如果试图重写函数以窃取值:
bob.sayName = function () { return secret.name; };
bob.sayName(); // window.secret.name; OR ERROR: can't call `name` of `undefined`
任何未在函数内部定义的函数都可以访问内部属性或方法
你可以用完全相同的方式拥有私有方法——事实上,所有这些函数都是私有的,直到我将它们都附加到public\u接口
对象(这就是我返回的)
如果您开始使用prototype
,请务必记住这一点
var Thing = function (secret) {};
Thing.prototype.sayName = function () { console.log("My name is " + secret.name); };
var thing = new Thing({ name : "Bob", age : 32 });
thing.sayName(); // "My name is undefined"
甚至原型函数都不能访问私有状态——它们必须使用公共状态(通过this
)
您可以使用更复杂的结构,使多个闭包具有public
、private
、private static
和public static
(这是prototype
最类似的)属性,但这在一开始就有点高级了,更让人困惑的是。JS中引用的任何都将公开访问
但是,由于闭包的概念,只需在函数中声明变量(或函数),就可以拥有完全私有的状态
此外,除非您希望通过编码获得原型,否则您甚至不需要新的
,也不需要这个
例如:
var makePerson = function (secret) {
var is_alive = true,
sayName = function () {
if (!is_alive) { return; }
console.log("My name is " + secret.name + ".");
},
sayAge = function () {
if (!is_alive) { return; }
console.log("My age is " + secret.age + ".");
},
haveBirthday = function () {
if (!is_alive) { return; }
secret.name += 1;
console.log("I'm " + secret.name +
", and today I turned " + secret.age + ".");
},
die = function () {
is_alive = false;
console.log(secret.name + " died today;" +
" they were " + secret.age + " year" +
(secret.age > 1 ? "s" : "") + " old." );
},
public_interface = { sayName : sayName,
sayAge : sayAge,
haveBirthday : haveBirthday,
die : die };
return public_interface;
};
var bob = makePerson({ name : "Bob", age : 32 });
任何人都不能从外面触摸secret.name
,secret.age
或是活着的
bob.name; // undefined
bob.is_alive = false; // Doesn't matter -- the code isn't relying on a public property.
bob.sayAge(); // "My age is 32"
bob.haveBirthday(); // "I'm Bob, and today I turned 33"
bob.die(); // "Bob died today; they were 33 years old"
更妙的是,JS允许您随时更改任务,因此您可能会担心以下情况:
// person overwriting the function
bob.haveBirthday = function () { is_alive = false; };
…但绝对没有理由害怕有人这样做,因为他们无法访问这些内部属性
bob.haveBirthday(); // window.is_alive = false;
bob.sayAge(); "My age is 33";
同样,如果试图重写函数以窃取值:
bob.sayName = function () { return secret.name; };
bob.sayName(); // window.secret.name; OR ERROR: can't call `name` of `undefined`
任何未在函数内部定义的函数都可以访问内部属性或方法
你可以用完全相同的方式拥有私有方法——事实上,所有这些函数都是私有的,直到我将它们都附加到public\u接口
对象(这就是我返回的)
如果您开始使用prototype
,请务必记住这一点
var Thing = function (secret) {};
Thing.prototype.sayName = function () { console.log("My name is " + secret.name); };
var thing = new Thing({ name : "Bob", age : 32 });
thing.sayName(); // "My name is undefined"
甚至原型函数都不能访问私有状态——它们必须使用公共状态(通过this
)
您可以使用更复杂的结构,使多个闭包具有public
、private
、private static
和public static
(这是prototype
最类似的)属性,但这在一开始就有点高级了,有点让人困惑。只是为了好玩(或者为了演示),我同时找到了另一个解决方案:
var Test = function(x){
var variables = function(){}
variables.variable = x;
this.getA = function(){
return variables.variable;
}
this.setA = function(x){
variables.variable = x;
}
}
测试结果如下:
var a = new Test("foo");
var b = new Test("baz");
alert(a.getA()); //"foo" as expected
alert(a.getA() == b.getA()); //false as expected
a.variable = "whatever";
alert(a.getA()); //"foo" as expected
alert(a.variable); //"whatever", doesn't seem preventable
a.setA("somewhere");
alert(a.getA()); //"somewhere", as expected
alert(a.variable); //"whatever", doesn't seem preventable
只是为了好玩(或为了演示),我同时找到了另一个解决方案:
var Test = function(x){
var variables = function(){}
variables.variable = x;
this.getA = function(){
return variables.variable;
}
this.setA = function(x){
variables.variable = x;
}
}
测试结果如下:
var a = new Test("foo");
var b = new Test("baz");
alert(a.getA()); //"foo" as expected
alert(a.getA() == b.getA()); //false as expected
a.variable = "whatever";
alert(a.getA()); //"foo" as expected
alert(a.variable); //"whatever", doesn't seem preventable
a.setA("somewhere");
alert(a.getA()); //"somewhere", as expected
alert(a.variable); //"whatever", doesn't seem preventable
你的期望是基于什么<代码>var变量
与该变量没有直接关系。变量
基于您的期望是什么var变量
与这个变量没有直接关系。变量
有趣的是,“this”有时会做什么-D非常感谢!“这个”有时真有趣-D非常感谢!难以置信,这正是我根本不懂的JS代码。也许我将来会学到这一点同时,我仍然使用“new”,因为这是自Javascript 1.2以来就存在的,并且是一个非常简单的方法+1用于在Javascript中使用快速数组。我个人将数组(JSON)用于数据结构(模型),而将普通对象用于控制器。虽然我看不出JS对象对于任何模型都有什么用途(好吧,数组也是对象,不是吗?),但我也看不出为什么命令“new”对于本地事件处理程序对象(“local”=浏览器中的永久对象)来说是件坏事