今、私はこれを実現するために懸命に検索しました: 完全なカプセル化を備えた完璧なクラスであり、インスタンス化に「新しい」必要はありません。しばらく検索した後、私はこれを思いつきました:
function Test(x){
var innerFunction = function(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new innerFunction(x);
}
しかし、テスト結果はそれが間違っていることを証明しました:
var a = Test("foo");
var b = Test("baz");
alert(a.constructor == b.constructor); //false, not good!
alert(a.constructor.name == b.constructor.name); //true
そのため、間違ったスコープがあるように見えたので、パブリック内部関数を使用しました:
function Test(x){
function innerFunction(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new innerFunction(x);
}
そして、いくつかの広範なテストを実行すると、それが正しいことが証明されました。
var a = Test("foo");
var b = Test("baz");
alert(a.constructor == b.constructor); //true, made it!
alert(a.constructor.name == b.constructor.name); //true
alert(a.getA()); //"foo" as expected
alert(a.getA() == b.getA()); //false as expected
a.variable = "whatever";
alert(a.getA()); //"foo" as expected
alert(a.variable); //"whatever", doesn't seem preventable
a.setA("somewhere");
alert(a.getA()); //"somewhere", as expected
alert(a.variable); //"whatever", doesn't seem preventable
しかし、このようにいくつかの関数を使用できますか? これが私の最初のアプローチでした:
function Test(x){
function innerFunction(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new innerFunction(x);
}
function TestToo(x){
function innerFunction(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new innerFunction(x);
}
var a = Test("foo");
var b = Test("baz");
var c = TestToo("foo");
var d = TestToo("baz");
alert(a.constructor == b.constructor); //true, as expected
alert(a.constructor.name == b.constructor.name); //true, as expected
alert(c.constructor == d.constructor); //true, as expected
alert(c.constructor.name == d.constructor.name); //true, as expected
alert(a.constructor == c.constructor); //false, as expected
alert(a.constructor.name == c.constructor.name); //true, as NOT expected
それで、これですか?文字列との比較のために、内部クラス構造を常に知る必要がありa.constructor.name
ますか? Nooooo、Javascriptでは文字通りすべてを行うことができるため(理由ではなく、方法を知る必要があるだけです)、この最終的な解決策を見つけました:
function Test(x){
function Test(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new Test(x);
}
function TestToo(x){
function TestToo(y){
var variable = y;
this.getA = function(){
return variable;
}
this.setA = function(x){
variable = x;
}
}
return new TestToo(x);
}
var a = Test("foo");
var b = Test("baz");
var c = TestToo("foo");
var d = TestToo("baz");
alert(a.constructor == b.constructor); //true, as expected
alert(a.constructor.name == b.constructor.name); //true, as expected
alert(c.constructor == d.constructor); //true, as expected
alert(c.constructor.name == d.constructor.name); //true, as expected
alert(a.constructor == c.constructor); //false, as expected
alert(a.constructor.name == c.constructor.name); //false, q.e.d.!
私は真剣です、なぜこれが機能するのかわかりません。しかし、100% 確実に動作し、100% オブジェクトがカプセル化され、Java クラスと 1:1 で同等です。;-)