ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript プロトタイプの継承_javascript スキルの落とし穴の簡単な分析

JavaScript プロトタイプの継承_javascript スキルの落とし穴の簡単な分析

WBOY
WBOYオリジナル
2016-05-16 17:10:51894ブラウズ

JavaScript はデフォルトでプロトタイプの継承を使用します。クラスの概念はありませんが、その関数はコンストラクターとして機能します。 this と new のコンストラクタを組み合わせると Java ライクなクラスを構築できます。したがって、JavaScript はそれ自体を拡張することでクラスベースの継承をエミュレートできます。

JavaScript は、他のオブジェクト指向言語と同様に、オブジェクト型の参照を使用します。オブジェクトを保持する変数は単なるアドレスですが、基本型データは値です。プロトタイプにオブジェクトを保存する場合、いくつかの落とし穴がある可能性があります。

最初の例を見てください

コードをコピーします コードは次のとおりです:

var create = function() {
function Fn() {}
return function(parent) {
Fn.prototype =parent
return new Fn
}
} ()

varparent = {
name: 'jack',
age: 30,
isMarried: false
}
var child = create( parent)
console.log(child)

作成ツール関数は、create が呼び出されるたびに、親オブジェクトに基づいて新しいオブジェクトがコピーされます。新しいオブジェクトのプロパティは親から取得されます。ここで、parent には 3 つの属性があり、それらはすべて文字列、数値、およびブール値の基本データ型です。

この時点で、親に影響するかどうかを確認するために子を変更します

コードをコピーします コードは次のとおりです:

child.name = 'lily'
child.age = 20,
child.isMarried = true

console.log(child)
コンソール.log(親)

結果は以下の通りです

つまり、子を変更しても親には影響しません。

別の例を見てください

コードをコピーします コードは次のとおりです:

var create = function() {
function Fn() {}
return function(parent) {
Fn.prototype =parent
return new Fn
}
}()

varparent = {
data: {
name: 'jack',
age: 30,
isMarried: false
},
language: ['Java' ]
}
var child = create(parent)

child.data.name = 'lily'
child.data.age = 20
child.data.isMarried = true
child. language.push('javascript')
console.dir(child)
console.dir(parent)

ここでのparentの2つの属性はデータであることに注意してください。それらは参照型であり、1 つはオブジェクト、もう 1 つは配列です。子は引き続き親から継承し、その後、子が変更されます。結果は次のようになります。

ご覧のとおり、この時点で親も変更されており、子の名前、年齢などは同じです。これは、プロトタイプ継承を使用するときに注意すべき点です。

継承を使用するより良い方法は次のとおりです:

1. データ属性はクラス継承 (これに依存) を採用しているため、パラメーターを使用して新しい属性を設定することもできます

2. このメソッドはプロトタイプの継承を採用しているため、メモリを節約できます。同時に、サブクラスによるメソッドのオーバーライドは親クラスに影響を与えません。

以下は上記 2 点を満たすライティングツールの機能です


コードをコピーします コードは次のとおりです:

/**
* @param {文字列} className
* @param {文字列/関数} superCls
* @param {関数} ファクトリー
 */
function $class(name, superClass, Factory) {
if (superClass === '') superClass = Object
function clazz() {
if (typeof this.init === 'function') {
this.init.apply(this, argument)
}
}
var p = clazz.prototype = new superCls
clazz.prototype.constructor = clazz
clazz.prototype.className = className
var supr = superCls.prototype
window[className] = clazz
Factory.call(p, supr)
}

オブジェクト型を親クラスのプロトタイプに配置する場合、サブクラスがそれを変更する場合、親クラスから継承したサブクラスのインスタンスはすべて次のようになります。変更されました。そして、これによって引き起こされるバグは見つけるのが非常に困難です。

ES5 では、プロトタイプの継承を実装するための新しい API Object.create が追加されています。次のように、これを使用して、上記の自己実装された作成関数を置き換えることができます。

コードをコピーします コードは次のとおりです。

varparent = {
name: 'jack',
age: 30,
isMarried: false
}
var child = Object.create(parent )
console.log(子)
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。