JavaScript はデフォルトでプロトタイプ継承を使用します。クラスの概念はありませんが、その関数はコンストラクターとして機能します。 this と new のコンストラクタを組み合わせると Java ライクなクラスを構築できます。したがって、JavaScript はそれ自体を拡張することでクラスベースの継承をエミュレートできます。
JavaScript は、他のオブジェクト指向言語と同様に、オブジェクト型の参照を使用します。オブジェクトを保持する変数は単なるアドレスですが、基本型データは値です。プロトタイプにオブジェクトを保存する場合、いくつかの落とし穴がある可能性があります。
まず最初の例を見てみましょう
次のようにコードをコピーします。
var create = function() {
関数 Fn() {}
戻り関数(親) {
Fn.prototype = 親
新しい Fn を返す
}
}()
親変数 = {
名前:「ジャック」、
年齢:30歳、
既婚: false
}
var child = 作成(親)
console.log(子)
作成ツール関数は、基本的なプロトタイプの継承を実装します。作成が呼び出されるたびに、新しいオブジェクトのすべてのプロパティが親オブジェクトに基づいてコピーされます。ここで、parent には 3 つの属性があり、それらはすべて文字列、数値、およびブール値の基本データ型です。
次に、子を変更して、親に影響を与えるかどうかを確認します。
次のようにコードをコピーします。
child.name = 'ユリ'
子供の年齢 = 20、
child.isMarried = true
console.log(子)
コンソール.ログ(親)
結果は次のとおりです
つまり、子を変更しても親には影響しません。
別の例を見てみましょう
次のようにコードをコピーします。
var create = function() {
関数 Fn() {}
戻り関数(親) {
Fn.prototype = 親
新しい Fn を返す
}
}()
親変数 = {
データ: {
名前:「ジャック」、
年齢:30歳、
既婚: false
}、
言語: ['Java']
}
var child = 作成(親)
child.data.name = 'ユリ'
child.data.age = 20
child.data.isMarried = true
child. language.push('javascript')
console.dir(子)
console.dir(親)
ここでの親の 2 つの属性、データと言語は両方とも参照型であり、1 つはオブジェクトで、もう 1 つは配列であることに注意してください。子は引き続き親から継承し、その後、子が変更されます。結果は次のようになります。
ご覧のとおり、この時点で親も変更されており、子の名前、年齢などは同じです。これは、プロトタイプ継承を使用するときに注意すべき点です。
継承を使用するより良い方法は次のとおりです。
1. データ属性はクラス継承 (これに依存) を採用しているため、新規作成時にパラメータを通じて設定することもできます。
2. このメソッドはプロトタイプ継承を採用しており、メモリを節約できます。同時に、サブクラスによるメソッドのオーバーライドは親クラスに影響を与えません。
上記2点を満たすライティングツールの機能は以下の通りです。
次のようにコードをコピーします。
/**
* @param {文字列} クラス名
* @param {文字列/関数} superCls
* @param {関数} ファクトリ
*/
関数 $class(名前、スーパークラス、ファクトリー) {
if (superClass === '') superClass = オブジェクト
functionclazz() {
if (typeof this.init === '関数') {
this.init.apply(this, 引数)
}
}
var p = clazz.prototype = 新しい superCls
clazz.prototype.constructor = clazz
clazz.prototype.className = クラス名
var supr = superCls.prototype
ウィンドウ[クラス名] = clazz
Factory.call(p、上)
}
親クラスのプロトタイプにオブジェクト型を配置するときは、サブクラスがそれを変更するときに注意してください。この場合、親クラスから継承するサブクラスのすべてのインスタンスが変更されます。そして、これによって引き起こされるバグは見つけるのが非常に困難です。
プロトタイプの継承を実装するための新しい API である Object.create が ES5 に追加されました。次のように、これを使用して、上記の自己実装された作成関数を置き換えることができます。
次のようにコードをコピーします。
親変数 = {
名前:「ジャック」、
年齢:30歳、
既婚: false
}
var child = Object.create(parent)
console.log(子)