JavaScriptアプリケーションを設定するには非常に多くの方法があるので、どちらが正しいか最良かについては混乱を招くようです。以下のテクニックに違いはありますか、これを行うより良い方法はありますか?
MyNamespace.MyClass = {
someProperty: 5,
anotherProperty: false,
init: function () {
//do initialization
},
someFunction: function () {
//do something
}
};
$(function () {
MyNamespace.MyClass.init();
});
別の方法:
MyNamespace.MyClass = (function () {
var someProperty = 5;
var anotherProperty = false;
var init = function () {
//do something
};
var someFunction = function () {
//do something
};
return {
someProperty: someProperty
anotherProperty: anotherProperty
init: init
someFunction: someFunction
};
}());
MyNamespace.MyClass.init();
最初のテクニックfeelsよりクラスに似ています。これが違いを生むのであれば、サーバーサイドのバックグラウンドから来ています。 2番目の手法はより冗長で少し扱いにくいように見えますが、これも多く使用されているようです。誰かが光を当てて前進するための最善の方法をアドバイスしてください。たくさんのクラスが互いに話し合っているアプリケーションを作りたい。
どちらもしないでください。
JavaScriptの「クラス」を作成します。
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass();
静的変数を持つもの:
var MyClass = (function(){
var static_var; //static private var
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
return MyClass;
})();
MyNamespace.MyClass = new MyClass();
「コンストラクター」を使用すると(すべての例には「コンストラクター」があり、この1つには処理するパラメーターがあります):
var MyClass = function (a, b c) {
//DO SOMETHING WITH a, b, c <--
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass(1, 3, 4);
上記のすべてを使用すると、できる:
MyNamespace.MyClass.someFunction();
しかし、あなたはできない(外部から):
MyNamespace.MyClass.privateFn(); //ERROR!
最初の例は、単純に オブジェクトリテラル です。インスタンス化できず、プライベートメンバーがありません。 2番目の例には、いくつかの誤った構文(var someProperty: 5
はvar someProperty = 5
)ただし、クロージャを使用して、内部的にプライベートな状態を自己呼び出し匿名関数内にカプセル化します。
2番目のアプローチは、プライベートメンバーをカプセル化するのに適していますが、インスタンス化可能なクラスにすることで、より「オブジェクト指向」にできます。
MyNamespace.MyClass = function() { ... };
MyNamespace.MyClass.prototype.someProperty = 'foo';
次に、「new」キーワードを使用してインスタンス化できます。
var aClass = new MyNamespace.MyClass();
aClass.init(...);
名前空間を持つインスタンス化可能なクラスに次の構文を使用します
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
使用しない理由
return { methodName : methodDelegate}
2番目の例のように:
MyNamespace.MyClass = (function () {
var someProperty = 5;
var init = function () {
//do something
};
return {
someProperty: someProperty
someFunction: someFunction
};
}());
MyNamespace.MyClass.init();
名前空間を使用するときは、インスタンスではなく宣言について考える必要があります。
MyNamespace = {};
MyNamespace.sub = {};
MyNamespace.anotherSub = {};
MyNamespace.sub.MyClass = (function () {
var static_var; //static private var
var MyClass2 = function () {
var privateVar; //private
var privateFn = function () { }; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
return MyClass2;
})();
debugger;
var c1 = new MyNamespace.sub.MyClass();
c1.someProperty = 1; // creates 5->1.
var c2 = new MyNamespace.sub.MyClass();
c2.someProperty = 2; // creates 5->2. c1 is still 1
debugger;
var myClass = function () {
var someProperty = 5;
var anotherProperty = false;
var init = function () {
//do something
};
var someFunction = function () {
//do something
};
return {
someProperty: someProperty,
anotherProperty: anotherProperty,
init: init,
someFunction: someFunction
};
};
MyNamespace.MyClass = myClass();
var c2 = MyNamespace.MyClass;
// how are planning to create one more object, while it's a reference? copy //the whole one?
c2.someProperty = 2; // changes 5 -> 2
var c3 = MyNamespace.MyClass.init(); // create 2 instead of 5
c3.someProperty = 3; // changes c3 and c3 from 2 to 3.
console.log(c2.someProperty + c3.someProperty);
また、モジュールのアンチパターがどれほど人気があったのか、ということもあります。宣言により、他の開発者が期待する方法で、異なるインスタンスで同じコードを使用することができます。コードの品質と読み取りの単純さが向上します。開発者の目標は、短いコードやD.R.Yではなく、読み取る単純なコードを書くことです。 -しかし、他の開発者が読んで理解するのは簡単です。最初にバグの数が減ります。 (c)S.マッコネル
名前空間とクラス宣言を組み合わせる方法:
var ns = { // your namespace
my_value: 1, // a value inside the namespace to avoid polluting
MyClass: function() { // a class inside the namespace
this.class_property: 12,
this.class_method: function() {
console.log("My property: " + this.class_property);
}
},
myFunction: function() { // a function inside a namespace
console.log("I can access namepsace value if you don't use 'new': " + this.my_value);
}
};
あなたの価値へのアクセス:
console.log(ns.my_value);
さて、クラスと関数について:new
を使用する場合、関数内のWord this
はそのコンストラクターを指します。 new
を使用しない場合、this
は名前空間を指します。そう、
クラスの使用:
var obj = new ns.MyClass();
関数の使用:
ns.myFunction();
new
を使用せずにオブジェクトを構築すると、this
は名前空間を指します。したがって、MyClass.class_property
およびMyClass.class_method
が追加されます。