用 getter 和 setter 封装在 JavaScript 中
Encapsulation in JavaScript with getter and setter
我知道有人问过这个问题,但已经研究过但失败了 - 抱歉!
我想尽可能简单的在JS中实现封装。我意识到 class 中的任何 'var' 都是私有的。
我只是不确定如何获取和设置任何私有变量的值。在下面的示例中,GETTING 和 SETTING 'colour' 的接口方法不起作用,因为这些函数无法访问对象的私有 'colour' 属性。我找不到一个明确的例子来说明如何实现它。
我什至不确定使用“.prototype”是将这些方法添加到 class 的最佳方式。
谢谢!
<button onclick="testOOP()">Click me</button>
<script>
//<!--
function testOOP(){
var v1 = new vehicle(4, "red"); //setting new values during instantiation
var v2 = new vehicle(2, "blue");
showVehDetails(v1);
showVehDetails(v2);
v2.wheels=1; //demonstrating no encapsulation
showVehDetails(v2);
v2.setcolour("orange"); //using an interface - fails
showVehDetails(v2);
}
function showVehDetails(v){
document.write("This vehicle is " + v.getcolour() + " and has " + v.getwheels() + " wheels.<br/>");
}
//*************'vehicle' - Class definition**************
function vehicle(thewheels, thecolour){
this.wheels = thewheels; //public property
var colour = thecolour; //private property
}
vehicle.prototype = {
constructor: vehicle,
getcolour: function(){
return this.colour; //but how to create a GETTER for colour?
},
getwheels: function(){
return this.wheels;
},
setwheels: function(newwheels){
this.wheels = newwheels;
},
setcolour: function(newcolour){ //and how to create a SETTER for colour?
this.colour = newcolour;
}
}
//************End class definition************************
//-->
</script>
在构造函数中声明的任何 var
s 将不存在于该构造函数之外。您需要将内容附加到 this 以便原型方法可以看到它。 JavaScript 没有私有成员的概念。
function Vehicle(thewheels, thecolour){
this.wheels = thewheels;
this.colour = thecolour;
}
Vehicle.prototype = {
getColour: function() {
return this.colour;
}
// etc
};
...但是您必须问问自己,让 getters/setters 围绕这些成员有什么好处?在 JavaScript 中很少使用 getter/setter 模式。通常您只需创建 public 成员。为成员使用 _
前缀之类的东西是向 "I know this is accessible, but you're not supposed to modify this directly."
发出信号的典型方式
如果你确实想让事情变得真实 "private," 你需要对闭包做一些技巧:
function Vehicle(theWheels, theColor) {
return {
getColour: function() { return theColor; },
setColour: function(value) { theColor = value; }
};
}
...但是这种方法的缺点是每个 Vehicle
对象都有自己的这些函数副本;您不会获得原型的记忆优势。
更新:
另请注意:如果您确实想通过包装方法来触发更改成员的逻辑,在现代 JS 中有更好的方法来创建 getter 和 setter:
function Vehicle(theWheels, theColor) {
this._wheels = theWheels;
this._color = theColor;
}
Vehicle.prototype = {
get color() { return this._color; },
set color(value) { this._color = value; console.log('Changed color'); },
get wheels() { return this._wheels; },
set wheels(value) { this._wheels = value; }
}
调用者只需像普通属性一样访问 .wheels
和 .color
,它将调用您的方法。
我知道有人问过这个问题,但已经研究过但失败了 - 抱歉!
我想尽可能简单的在JS中实现封装。我意识到 class 中的任何 'var' 都是私有的。
我只是不确定如何获取和设置任何私有变量的值。在下面的示例中,GETTING 和 SETTING 'colour' 的接口方法不起作用,因为这些函数无法访问对象的私有 'colour' 属性。我找不到一个明确的例子来说明如何实现它。
我什至不确定使用“.prototype”是将这些方法添加到 class 的最佳方式。
谢谢!
<button onclick="testOOP()">Click me</button>
<script>
//<!--
function testOOP(){
var v1 = new vehicle(4, "red"); //setting new values during instantiation
var v2 = new vehicle(2, "blue");
showVehDetails(v1);
showVehDetails(v2);
v2.wheels=1; //demonstrating no encapsulation
showVehDetails(v2);
v2.setcolour("orange"); //using an interface - fails
showVehDetails(v2);
}
function showVehDetails(v){
document.write("This vehicle is " + v.getcolour() + " and has " + v.getwheels() + " wheels.<br/>");
}
//*************'vehicle' - Class definition**************
function vehicle(thewheels, thecolour){
this.wheels = thewheels; //public property
var colour = thecolour; //private property
}
vehicle.prototype = {
constructor: vehicle,
getcolour: function(){
return this.colour; //but how to create a GETTER for colour?
},
getwheels: function(){
return this.wheels;
},
setwheels: function(newwheels){
this.wheels = newwheels;
},
setcolour: function(newcolour){ //and how to create a SETTER for colour?
this.colour = newcolour;
}
}
//************End class definition************************
//-->
</script>
在构造函数中声明的任何 var
s 将不存在于该构造函数之外。您需要将内容附加到 this 以便原型方法可以看到它。 JavaScript 没有私有成员的概念。
function Vehicle(thewheels, thecolour){
this.wheels = thewheels;
this.colour = thecolour;
}
Vehicle.prototype = {
getColour: function() {
return this.colour;
}
// etc
};
...但是您必须问问自己,让 getters/setters 围绕这些成员有什么好处?在 JavaScript 中很少使用 getter/setter 模式。通常您只需创建 public 成员。为成员使用 _
前缀之类的东西是向 "I know this is accessible, but you're not supposed to modify this directly."
如果你确实想让事情变得真实 "private," 你需要对闭包做一些技巧:
function Vehicle(theWheels, theColor) {
return {
getColour: function() { return theColor; },
setColour: function(value) { theColor = value; }
};
}
...但是这种方法的缺点是每个 Vehicle
对象都有自己的这些函数副本;您不会获得原型的记忆优势。
更新:
另请注意:如果您确实想通过包装方法来触发更改成员的逻辑,在现代 JS 中有更好的方法来创建 getter 和 setter:
function Vehicle(theWheels, theColor) {
this._wheels = theWheels;
this._color = theColor;
}
Vehicle.prototype = {
get color() { return this._color; },
set color(value) { this._color = value; console.log('Changed color'); },
get wheels() { return this._wheels; },
set wheels(value) { this._wheels = value; }
}
调用者只需像普通属性一样访问 .wheels
和 .color
,它将调用您的方法。