コンストラクタ内の方法とコンストラクタprototype属性上の方法の比較
4297 ワード
非常に有用な文章です.今日はまた、構造関数についての方法と原型についての質問があります.構造関数の方法は関数の内容を定義しています.プライベートな方法として、公開していません.プロトタイプは対象によって定義されます.
まずこの文章のポイントを理解します.関数内の方法:関数内の方法を使うと、関数内部のプライベート変数にアクセスできます.構造関数newを通して出てきたオブジェクトが、構造関数内部のプライベート変数を操作する必要があるなら、この時は関数内の方法を考慮します. prototype上の方法:一つの関数を通して大量のオブジェクトを作成する必要があり、これらのオブジェクトはまだ多くの方法がある場合.このとき、私たちは関数のプロトタイプにこれらの方法を追加することを考慮します.この場合、私たちのコードのメモリ占有率は比較的小さいです. は、実際のアプリケーションでは、これらの2つの方法はしばしば組み合わせて使用される.私たちはまず私たちが必要なものを知ってから、どのように使うかを選択します.
私達はやはり下のコードでこれらのポイントを説明しましょう.以下はコードの部分です.
この二つの構造関数newを通して出てくるオブジェクトは同じ属性と方法を持っているが、その違いは次の図で説明できる.
私たちは、構造関数
この方法はコンストラクタ内部で定義されています.各例でクローンされます.構造関数の
もちろん、いくつかの場合には、構造関数にいくつかの方法を定義する必要があります.この場合は、構造関数内部の私有変数にアクセスする必要があります.
二つの組み合わせの例を挙げます.コードは以下の通りです.
方法をコンストラクタの内部に書いて、コンストラクタを通じて一つのオブジェクトを初期化するコストが増えました.このようなコストは
また、注意すべき点は: まず関数のprototype属性で方法を定義するなら、覚えておきたいのですが、方法を変えると、この構造関数によって生成されるすべてのオブジェクトのその方法が変更されます. もう一つのポイントは変数の引き上げの問題です.以下のコードを少し見てもいいです. オブジェクトの順序付けに関する問題.関数の
JavaScript , prototype ; .
読みやすいように、構造関数に方法を書く場合は、私達は単に
といいます.方法をprototype属性に書く場合は、私達は単にprototype
といいます.まずこの文章のポイントを理解します.
私達はやはり下のコードでこれらのポイントを説明しましょう.以下はコードの部分です.
// A
function A(name) {
this.name = name || 'a';
this.sayHello = function() {
console.log('Hello, my name is: ' + this.name);
}
}
// B
function B(name) {
this.name = name || 'b';
}
B.prototype.sayHello = function() {
console.log('Hello, my name is: ' + this.name);
};
var a1 = new A('a1');
var a2 = new A('a2');
a1.sayHello();
a2.sayHello();
var b1 = new B('b1');
var b2 = new B('b2');
b1.sayHello();
b2.sayHello();
まず二つのコンストラクタを書きました.第一はA
で、このコンストラクタには一つの方法sayHello
が含まれています.第二は、構造関数B
であり、その方法sayHello
を、構造関数B
のprototype
の属性の上に書いている.この二つの構造関数newを通して出てくるオブジェクトは同じ属性と方法を持っているが、その違いは次の図で説明できる.
私たちは、構造関数
A
を使用して、2つのオブジェクトを作成しました.それぞれa1
、a2
です.構造関数Bによって2つのオブジェクトb1
、b2
が作成された.b1
、b2
の2つのオブジェクトのうちのsayHello
方法は、それらの構造関数のprototype
属性を指すsayHello
の方法であることが分かります.a1
、a2
は、すべて自分の内部でこの方法を定義しています.この方法はコンストラクタ内部で定義されています.各例でクローンされます.構造関数の
prototype
属性に定義された方法は、この方法をすべての例で共有するが、この方法は各例の内部では再定義されない.もし私たちのアプリケーションが多くの新しいオブジェクトを作成する必要があるならば、メモリを節約するために、これらの方法を構造関数のprototype
属性に定義することを提案する.もちろん、いくつかの場合には、構造関数にいくつかの方法を定義する必要があります.この場合は、構造関数内部の私有変数にアクセスする必要があります.
二つの組み合わせの例を挙げます.コードは以下の通りです.
function Person(name, family) {
this.name = name;
this.family = family;
var records = [{type: "in", amount: 0}];
this.addTransaction = function(trans) {
if(trans.hasOwnProperty("type") && trans.hasOwnProperty("amount")) {
records.push(trans);
}
}
this.balance = function() {
var total = 0;
records.forEach(function(record) {
if(record.type === "in") {
total += record.amount;
}
else {
total -= record.amount;
}
});
return total;
};
};
Person.prototype.getFull = function() {
return this.name + " " + this.family;
};
Person.prototype.getProfile = function() {
return this.getFull() + ", total balance: " + this.balance();
};
上記のコードでは、Person
コンストラクションを定義しました.この関数には、内部のプライベート変数records
があります.この変数は、関数の内部以外の方法でこの変数を操作したくないので、この変数を操作する方法を関数の内部に書いて、公開できる方法をPerson
のprototype
属性に書いています.例えば、方法getFull
とgetProfile
.方法をコンストラクタの内部に書いて、コンストラクタを通じて一つのオブジェクトを初期化するコストが増えました.このようなコストは
prototype
属性に書くと効果的に減少します.オブジェクトを呼び出す方法はプロトタイプチェーンを呼び出す方法よりずっと速いと感じるかもしれません.実はそうではありません.もしあなたのオブジェクトの上に多くのプロトタイプがあるのではないなら、彼らのスピードは同じぐらいです.また、注意すべき点は:
func1(); // , ,func1 . error: func1 is not a function
var func1 = function() {
console.log('func1');
};
func2(); // , .
function func2() {
console.log('func2');
}
prototype
上に定義されている属性は、順序付けされないので、下記のコードを参照してください.function A(name) {
this.name = name;
}
A.prototype.sayWhat = 'say what...';
var a = new A('dreamapple');
console.log(JSON.stringify(a));
私たちは出力結果を見ることができます.{"name":"dreamapple"}
です.