継承を使用したい場合は、できません(少なくとも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/
コンストラクター関数の表記法に慣れている場合は、次のようにすることができます。
(未検証)
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);};
}
プロトタイプは使用されず、メソッドはオブジェクトに直接コピーされるため、これは上記とほとんど同じです。
ただし、クロージャのアプローチはメモリと時間がかかり、最悪の場合、作業しているオブジェクトに実際には属していない変数を使用します...これは重要な「セマンティック」問題です (このプロップは属しますか)私にとって、またはそうでない? ) 継承が頭痛の種になります。この理由は、拡張オブジェクトのメソッドがそのプライベート疑似プロパティにアクセスできないか (スーパーオブジェクト クロージャで定義されていないため)、または「スーパーオブジェクト」から共通のプライベート変数にアクセスできるためです (メソッドはスーパーオブジェクトで定義されているため、スーパーオブジェクトのクロージャーにアクセスします)。それはナンセンスです。
「文化的」アプローチ
私の謙虚な意見では、カプセル化は、誰かがあなたのコードをいじるのを防ぐことはできません.このプロパティは外部から使用しないでください。」たとえば、プライベート プロパティの前に '_' を付けます。これは、それらがプライベート、保護、またはその他のものであることを意味しますが、それから離れていることを意味します。そして触れてはいけないものには触れない。
このアプローチは、最も単純で最も効率的であるだけでなく、プロパティがオブジェクト内にあり、クロージャーに限定されないため、継承チェーンを操作できます。
var Person = function (name) {
this._name = name;
}
Person.prototype.sayHello = function () {...};
Person.prototype.getName = function () {...};
Person.prototype.setName = function () {...};