我正在使用这样的 JavaScript 对象:
var obj = new Foob;
我应该假装有一种私人方式并做:
obj.get('foo');
还是我应该尝试直接访问:
obj.foo
我正在使用这样的 JavaScript 对象:
var obj = new Foob;
我应该假装有一种私人方式并做:
obj.get('foo');
还是我应该尝试直接访问:
obj.foo
您实际上可以拥有只能通过 Javascript 中的 setter 和 getter 访问的变量:
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;
}
}
Javascript 的一个鲜为人知的特性是它原生支持 getter 和 setter。
定义属性时,您可以通过以下方式简单地定义它:
someObj.prop = 12;
或者您可以定义 getter 和 setter ,使用Object.defineProperty
和 保留字get
and set
:
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。
显然,使用 getter/setters 代码并没有太大的兴趣,除非您想进行边界检查/类型检查或有其他特定原因。
当我开始大量使用面向对象的 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 语法的缺点是它实际上并没有使您的变量私有,它只是“隐藏”它以便您可以使用一些秘密的内部名称,除非您按照文森特的指示在构造函数中定义它。
要真正做到私密:
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);