Heim > Artikel > Web-Frontend > js-Vererbungsimplementierung
Vorwort
JS ist eine objektorientierte, schwach typisierte Sprache, Vererbung ist auch sehr leistungsfähig Eines der Merkmale. Wie implementiert man also die Vererbung in JS? Warten wir ab.
Da wir die Vererbung implementieren möchten, müssen wir zuerst eine übergeordnete Klasse haben, der Code lautet wie folgt:
// 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };
Kern: Verwenden Sie die Instanz der übergeordneten Klasse als Prototyp der untergeordneten Klasse
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.eat('fish')); console.log(cat.sleep()); console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true
Eigenschaften:
Eine sehr reine Vererbungsbeziehung, die Instanz ist das untergeordnete Element. Eine Instanz einer Klasse ist auch eine Instanz der übergeordneten Klasse
Die übergeordnete Klasse fügt neue Prototypmethoden/Prototypattribute hinzu, die sein können Zugriff durch Unterklassen
Einfach, leicht zu implementieren
Nachteile:
Wenn Sie möchten Wenn Sie einer Unterklasse Attribute und Methoden hinzufügen, müssen Sie einer Anweisung wie new
Animal()
Ausführung folgen, kann nicht im Konstruktor platziert werden
Mehrfachvererbung kann nicht implementiert werden
Referenzeigenschaften aus dem Prototypobjekt werden von allen Instanzen gemeinsam genutzt (bitte fragen Sie nach Einzelheiten. Siehe Anhangcode: Beispiel 1)
Beim Erstellen einer Unterklasseninstanz können keine Parameter übergeben werden zum übergeordneten Klassenkonstruktor
Empfohlener Index: ★★ (Zwei schwerwiegende Fehler in 3 und 4)
Kern: Die Verwendung des Konstruktors der übergeordneten Klasse zum Erweitern der Unterklasseninstanz entspricht dem Kopieren der übergeordneten Klasse. Geben Sie Unterklassen Instanzattribute (es wird kein Prototyp verwendet)
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
Funktionen:
Lösen Sie das Problem in 1, dass Unterklasseninstanzen Referenzattribute der übergeordneten Klasse gemeinsam nutzen
Beim Erstellen einer Unterklasseninstanz können Sie Parameter an die übergeordnete Klasse übergeben
Sie können Mehrfachvererbung implementieren (mehrere übergeordnete Klassenobjekte aufrufen)
Nachteile:
Instanzen sind keine Instanzen von Die übergeordnete Klasse, aber nur Instanzen der Unterklasse
können nur vererbt werden. Die Instanzattribute und -methoden der übergeordneten Klasse können die Prototypattribute/-methoden nicht erben
Funktionswiederverwendung kann nicht erreicht werden. Jede Unterklasse verfügt über eine Kopie der übergeordneten Klasseninstanzfunktion, was sich auf die Leistung auswirkt
Empfehlungsindex: ★★ (Nachteil 3)
Kern: Fügen Sie neue Funktionen zu übergeordneten Klasseninstanzen hinzu, da die Unterklasseninstanz
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
Funktionen:
zurückgibt不限制调用方式,不管是new
子类()
还是子类()
,返回的对象具有相同的效果
缺点:
实例是父类的实例,不是子类的实例
不支持多继承
推荐指数:★★
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特点:
支持多继承
缺点:
效率较低,内存占用高(因为要拷贝父类的属性)
无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
推荐指数:★(缺点1)
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true
特点:
弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
既是子类的实例,也是父类的实例
不存在引用属性共享问题
可传参
函数可复用
缺点:
调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
推荐指数:★★★★(仅仅多消耗了一点内存)
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super(); })(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true
特点:
堪称完美
缺点:
实现较为复杂
推荐指数:★★★★(实现复杂,扣掉一颗星)
示例一:
function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } //实例引用属性 this.features = []; } function Cat(name){ } Cat.prototype = new Animal(); var tom = new Cat('Tom'); var kissy = new Cat('Kissy'); console.log(tom.name); // "Animal" console.log(kissy.name); // "Animal" console.log(tom.features); // [] console.log(kissy.features); // [] tom.name = 'Tom-New Name'; tom.features.push('eat'); //针对父类实例值类型成员的更改,不影响 console.log(tom.name); // "Tom-New Name" console.log(kissy.name); // "Animal" //针对父类实例引用类型成员的更改,会通过影响其他子类实例 console.log(tom.features); // ['eat'] console.log(kissy.features); // ['eat'] 原因分析: 关键点:属性查找过程 执行tom.features.push,首先找tom对象的实例属性(找不到), 那么去原型对象中找,也就是Animal的实例。发现有,那么就直接在这个对象的 features属性中插入值。 在console.log(kissy.features); 的时候。同上,kissy实例上没有,那么去原型上找。 刚好原型上有,就直接返回,但是注意,这个原型对象中features属性值已经变化了。 本文讲解了js的继承实现相关内容,更多相关内容请关注php中文网。 相关推荐:
Das obige ist der detaillierte Inhalt vonjs-Vererbungsimplementierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!