web-dev-qa-db-ja.com

コンストラクター内でコンストラクターのプロトタイプにアクセスするのは悪いことですか?

コンストラクター用に定義されたプロトタイプを見たほとんどの場所は、そのように行われました。

var Person = function(){
    this.stuff = stuff;
}
Person.prototype.doSomething = function(){console.log("something")}
var john = new Person();

しかし、私には、Javaから来るので、コンストラクター内で直接定義する方が直感的です。

var Person = function(){
    this.stuff = stuff;
Person.prototype.doSomething = function(){console.log("something")}
}
var john = new Person();

しかし、私が以前にそのように行われたのを見たことがないという事実は、そのようにそれを行うことに何か問題があるのではないかと思います。それは私が予見していなかった問題を引き起こしますか?

4
Supetorus

JavaScriptの「コンストラクター」に関数を設定することの全体的なポイントは、インスタンスにアクセスしたときにプロトタイプチェーンに関数が設定されるようにすることです。

例A
function Foo() {...}
Foo.prototype.bar = function () {...}
var foo = new Foo();
foo.bar(); //references the shared function on the constructor

別の方法として、コンストラクター内のインスタンスに関数を直接設定することもできます。

例B
function Foo() {
  this.bar = function () {...};
}
var foo = new Foo();
foo.bar(); //references the function set directly on the instance

これら2つの方法の違いは、作成される関数の数にあります。

例AでFooの1000個のインスタンスを生成すると、正確に1つのbarメソッドが定義され、allインスタンス。

例BでFooの1000個のインスタンスを生成すると、10メソッドが作成されます。インスタンスごとに1つ。これはスコープ変数にアクセスするのに役立ちますが、明らかなパフォーマンスコストが伴います。


代わりに、コンストラクターのプロトタイプinsideに関数を追加する場合...

例C :(これは絶対に行わないでください)
function Foo() {
  Foo.prototype.bar = function () {...};
}
var foo = new Foo();
foo.bar(); //references the shared function on the constructor

両方の方法の中で最悪の方法があります。プロトタイプが共有されているため、スコープ変数を完全に利用することはできません。そのため、すべてのインスタンスが使用可能な関数とスコープを上書きし、インスタンスごとに新しい関数を生成しますand既存の関数をすべて破棄します。

そのような方法でJavaScriptを記述しないでください。


tl; dr:

コンストラクター内でコンストラクターのプロトタイプにアクセスするのは悪いことですか?

はい

5
zzzzBov