我正在使用这样的JavaScript对象:
var obj = new Foob;
我应该假装有一种私人方式并且做:
obj.get('foo');
或者我应该尝试直接访问:
obj.foo
答案 0 :(得分:12)
实际上你可以拥有只能通过Javascript中的setter和getters访问的变量:
function Foob(){
var foo = 5;
this.getFoo = function(){
return foo;
}
this.setFoo = function(newFoo){
foo = newFoo;
return this;
}
}
var obj = new Foob;
obj.getFoo(); // 5
obj.foo; // undefined
或者如果你想要一个通用的getter / setter:
function Foob(){
// You can set default values in the data object
var data = {};
this.get = function(key){
return data[key];
}
this.set = function(key, value){
data[key] = value;
return this;
}
}
答案 1 :(得分:7)
Javascript的一个最不为人所知的特性是它本身支持getter和setter 定义属性时,您可以通过以下方式定义它:
someObj.prop = 12;
或者您可以使用Object.defineProperty
和保留字get
和set
来定义getter和setter:
Object.defineProperty ( someObj, "prop" ,
{ get : function () { return ??; } ,
set : function (val) { /* store val */ } } ;
在“类”中使用此类getter / setter获取私有变量的方法是:
var MyClass = function() {
var _private = 5;
Object.defineProperty(this, "public", {
get : function() { return _private; },
set : function(val) { _private=val; }
});
return this;
};
var anInstance = new MyClass();
anInstance.public = 12 ;
console.log(anInstance.public) ; // writes 12
console.log(anInstance._private) ; // writes undefined.
所以你有一个真正的私人变量,配有一个吸气剂和一个二传手。
显然,使用getter / setter代码没什么兴趣,除非你想进行边界检查/类型检查或者有其他特定原因。
答案 2 :(得分:4)
当我开始大量使用面向对象的JavaScript时,我曾经喜欢getter和setter的想法,但那是因为我来自Java背景。
ES5通过特殊语法支持getter和setter
见John Resig的解释:
http://ejohn.org/blog/javascript-getters-and-setters/
我的想法是考虑为什么getter / setter有用。这样就可以封装变量的访问权限,从而可以拦截/控制变量的访问权限。如果调用代码直接改变另一个对象的实例变量,那么你就无法透明地改变它。需要捕获所有这些突变需要更改变量范围,添加getter和setter以及更改所有调用代码。
但是,这种语法对于调用代码是透明的。因此,您可以简单地允许直接控制属性,然后如果您需要拦截它,例如添加一个console.log进行调试,您可以添加一个getter和setter,它就可以正常工作。
function Foob() {
}
Foob.prototype = {
get foo() {
return this._foo;
},
set foo(foo) {
this._foo = foo;
}
};
var o = new Foob();
console.log(o.foo);
getter / setter语法的缺点是它实际上并不使你的变量变为私有,它只是“隐藏”它以便你可以使用一些秘密的内部名称,除非你在构造函数中定义它,如Vincent所示。
要获得真正的私密性:
function Foob() {
var foo;
this.__defineGetter__('foo', function () {
return foo;
});
this.__defineSetter__('foo', function (_foo) {
foo = _foo;
});
}
var o = new Foob();
console.log(o.foo);