如果你想使用继承,你不能(至少 AFAIK)。但是,对于没有继承链的对象,您可以使用闭包来获得完全相同的效果。问题是您是否真的需要真正完全私有的属性。
闭包方法
您可以执行一个函数,该函数的闭包包含您想要私有的变量。这些私有变量实际上并不属于对象,而只能被对象的方法访问。例如:
var getPersonInstance = function (name) {
// Those are "private" properties
var myName = name;
return {
getName: function () {
return myName
},
setName: function (name) {
myName = name;
},
sayHello = function () {
alert('hello! my name is ' + myName);
}
}
};
var person = getPersonInstance('Juan');
person.getName(); // Returns Juan
person.myName = 'Don Vito' // This sets the person.myName property, which is not the one in the closure
person.setName('John') // Works
person.sayHello(); // alert hello! my name is John
你可以在这里查看:
http://jsfiddle.net/MLF7v/1/
如果您对 Constructor 函数表示法感觉更舒服,您可以执行以下操作:
(未测试)
function Person(name) {
// Anything that is not attached to this will be private
var myName = name;
this.getName = function () { return myName;};
this.setName = function (newName) {myName = newName;};
this.sayHello = function () {alert('hey there, my name is' + myName);};
}
这与上面几乎相同,因为没有使用原型并且方法直接复制到对象中。
但是,闭包方法是内存和耗时的,最糟糕的是:它们使用实际上不属于您正在使用的对象的变量......这是一个重要的“语义”问题(这个道具是否属于对我来说,还是不是?)这让继承很头疼。这样做的原因是,扩展对象的方法要么无法访问该私有伪属性(因为它们没有在超级对象闭包中定义),要么可以访问来自“超级对象”的公共私有变量(方法是在超对象中定义的,因此可以访问超对象的闭包)。那是胡说八道。
“文化”方法
以我的拙见,封装并不能阻止任何人如果他/她真的想弄乱你的代码,所以我更喜欢遵循 python 哲学“我们都是成熟的人”,其中包括使用约定说“我想要此属性不得从外部使用”。例如,我在私有属性前面加上“_”,这意味着它们是私有的、受保护的或其他任何东西,但只是远离它。你不要碰你不应该碰的东西。
这种方法除了是最简单和最有效的方法外,还允许您使用继承链,因为属性在对象中,而不是限制在闭包中。
var Person = function (name) {
this._name = name;
}
Person.prototype.sayHello = function () {...};
Person.prototype.getName = function () {...};
Person.prototype.setName = function () {...};