2012-01-01 17 views
3

私はJSでオブジェクトを持つ最も最適な方法を探しています。 JSでは複数の方法で何かを行うことができますので、どちらが「ベストプラクティス」であるかを知りたいと思っています。JSオブジェクトを作成する最も最適化された方法

オブジェクトの概念的な使用は、このようになります:

var John = new Person('John'); 
var Foo = new Person('Foo'); 

console.log(John.getName()); //Return 'John' 
console.log(Foo.getName()); //Return 'Foo' 
console.log(John.name); //undefined 
console.log(Foo.name); //undefined 

私はここにいくつかの例があります

例1:ここ

var Person = function (name) { 
    this.getName = function() { return name; } 
} 

私は実際には特性を有していません。 "name"は変更できません。publicでgetNameメソッドをpublicにアクセスし、local name変数で呼び出すことができます。これは実際に私のニーズを満たしています。

例#2:これは、例1と同様の挙動を有する

function Person (name) { 
    this.getName = function() { return name; } 
} 

。機能とパフォーマンスの観点から、var method = function() {};function method() {};の違いについてはわかりません。

例#3:

var Person = function (name) { 
    this.name = name;  
    Person.prototype.getName = function() { return this.name; } 
} 

ここで私は、公共によってリード/ライトを、私はまた、公共アクセスすることができ、プロトタイプgetNameメソッドを持つことができnameプロパティを持っています。

例#4:ここで

var Person = function (name) { 
    this.name = name; 
    if (!Person._prototyped) { 
     Person.prototype.getName = function() { return this.name; } 
     Person._prototyped = true; 
    } 
} 

私は私が必要な時にプロトタイプのメソッドは一度だけしか設定されていることを確認して違いを例#3に持っていたものを持っています。

最終的な質問は、あなたが私に従うように提案するものか、あるいはそれらのいずれかがベストプラクティスであるかどうかです。

+0

public * name *プロパティはありませんが、* getName *はpublicであり、有効に置き換えることができます* name *は変更できます。上記は、public * name *プロパティには何のメリットもありません。クロージャーにはより多くのリソースを使用し、値にアクセスするには余分な関数呼び出しを使用します。しかし、ゲッターの使用には正当な理由があります。 – RobG

答えて

3

をホープ、最良の方法は、おそらくこれです:

/** 
* @constructor 
*/ 
function Person(name) { 
    this.getName = function() { 
     return name; 
    }; 
} 

これはなぜでしょうか?まあ、まずカプセル化。可能な場合は、一般的にそうように、プロトタイプで関数を入れたい:しかし

/** 
* @constructor 
*/ 
function Person(name) { 
    this.name = name; 
} 

Person.prototype.getName = function() { 
    return this.name; 
}; 

この場合、Person.nameにアクセスしたくないと思われます。そのため、クロージャを使用する必要があります。この方法としては

:良いではありません

var Person = function (name) { 
    this.name = name;  
    Person.prototype.getName = function() { return this.name; } 
} 

this.nameを公開していますので、以前のプロトタイプの方法に比べて利点はありませんが、同じ機能で継続的にPerson.prototype.getNameを上書きします。それには何の意味もありません。 thisは毎回適切なオブジェクトになります。さらにPerson.prototype.getNameは最初のPersonオブジェクトがインスタンス化されるまでアクセスできませんので、最初は "public"にすることに多くのポイントがありません。あなたの4番目の例は基本的に同じですが、より多くの荒れ狂いを理解するのが難しくなりますが、まだすべての欠点があります。

だから、この場合、最初のバージョンに行ってください。可能であれば、prototypeにメソッドを設定して、インスタンス外で呼び出すことができます。

最後に、私が使用することをお勧めします:1)は、第2の例では、セミコロンが欠落しているため、2)varコンストラクタは、それがすべき変数であることを意味し、

function Person() { 
} 

var Person = function() { 
} 

を3)JDocが@constructorをそれに適用できるとは思わないので、クロージャコンパイラで少なくともという警告が表示されます。


オーケー

、それほど重要ではありません。しかしまだ...

+0

こんにちは、返信ありがとう!:)ちょうど質問、私たちは、プロパティは、あなたが好むとどのような方法で一般公開される場合、私は気にしないとなぜですか?おそらく性能問題のための方法をプロトタイピングすることによって、正しいでしょうか? – panosru

+1

@panosru:おそらくメソッドのプロトタイプを作成します。より効果的かもしれませんが、重要なことは 'Person.prototype.getName.call(someObj)'のようなことができることです。 – Ryan

+1

あなたが好きな理由とその理由は何ですか? { this.getName = function(){return name; } } ' #2 ' function Person(name){ return { } getName:function(){戻り値; } } } ' – panosru

2

例3および4では、それは次のようになります。

var Person = function (name) { 
    this.name = name;  
}; 
Person.prototype.getName = function() { return this.name; } 

そして:

var Person = function (name) { 
    this.name = name; 
}; 

if (!Person._prototyped) { 
    Person.prototype.getName = function() { return this.name; } 
    Person._prototyped = true; 
} 

あなたはプロトタイプを台無しにあなたはコンストラクタを呼び出すたびに必要としないと。

どのようなものがあなたの目的に合っているかはわかりませんが、それはあなたの求めるものですが、マイクロ最適化のように思われるので心配しません。あなたは、あなたがhttp://jsperf.com/

のようなサイトを使用することができます知っている必要がある場合は、私が想像することができる最速の方法は次のようになります。

function Person(name) { 
    this.getName = function() { 
     return name; 
    }; 
} 

minitechが言ったように。理由は次のとおりです。

jsエンジンがプロトタイプチェーンを「上に」移動するたびに、msの分数(またはIEの分数)がかかります。変数の宣言には、あなたはそれをやることも避けてください。それはあなたが望むもののために

+0

例#3については、私はあなたに同意しますが、例#4の理由は何ですか?フラグが配置されているので、プロトタイピングは実際には複数回、必要な場合にのみ設定されることはありません。 – panosru

+0

@panosru:チェック( 'if')もある程度の計算能力と時間を要するためです。 – qwertymk

+0

もちろん、もちろんですが、このように正しく使用することを意味する「問題」はありません。私は実際にそれを使用していない私はちょうどここでそれを見た:http://stackoverflow.com/a/546717/395187それは私が尋ねた理由:) – panosru

0

node.jsでうまく動作します。 AFAIK、引数は変更可能です。クロージャーは価値を覚えています。したがって、これは動作します。私はこれがそれをすべて解決すると思います。

var Person = function(Name) { 
    this.getName = function(){return Name;} 
    this.setName = function(newName) { Name = newName; } 
}, 

me = new Person('John'); 
console.log(me.getName()); 
me.setName('Peter'); 
console.log(me.getName()); 
関連する問題