Dieser Artikel gibt Ihnen Beispiele für gängige Vererbungsmethoden in js? (Mit Beispielen) hat es einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen.
Ein sehr wichtiger Aspekt der objektorientierten Programmierung ist die Objektvererbung. Durch die Vererbung des B-Objekts kann das A-Objekt direkt alle Eigenschaften und Methoden des B-Objekts besitzen. Dies ist sehr nützlich für die Wiederverwendung von Code.
Die meisten objektorientierten Programmiersprachen implementieren die Objektvererbung durch „Klassen“. Traditionell wird die Vererbung der JavaScript-Sprache nicht über Klassen implementiert (ES6 führte die Klassensyntax ein), sondern über „Prototypen“. Was sind also die gängigen Vererbungsmethoden in JS?
Wenn Sie den Quellcode dieses Artikels wünschen, klicken Sie bitte auf Sechs gängige Vererbungsmethoden
Methode 1. Prototypkettenvererbung
Der Schlüssel zu dieser Methode ist: Der Prototyp des Untertyps ist ein Instanzobjekt des übergeordneten Typs.
//父类型 function Person(name, age) { this.name = name, this.age = age, this.play = [1, 2, 3] this.setName = function () { } } Person.prototype.setAge = function () { } //子类型 function Student(price) { this.price = price this.setScore = function () { } } Student.prototype = new Person() // 子类型的原型为父类型的一个实例对象 var s1 = new Student(15000) var s2 = new Student(14000) console.log(s1,s2)
Aber die Essenz dieser Methode besteht darin, den Prototyp der Unterklasse auf die Instanz der übergeordneten Klasse zu verweisen, also der Unterklasse Die Instanz kann über __proto__, die Instanz von Person, auf Student.prototype zugreifen, sodass Sie auf die privaten Methoden der übergeordneten Klasse zugreifen und dann mit __proto__ auf den Prototyp der übergeordneten Klasse verweisen und die Methoden abrufen können Prototyp der übergeordneten Klasse. Daher werden die privaten und öffentlichen Methoden und Eigenschaften der übergeordneten Klasse als öffentliche Eigenschaften der Unterklasse behandelt.
Die untergeordnete Klasse erbt die Eigenschaften und Methoden der übergeordneten Klasse und behandelt die privaten Eigenschaften und öffentlichen Methoden der übergeordneten Klasse als Unsere eigenen öffentlichen Attribute und Methoden , wir alle wissen, dass wir bei der Bearbeitung von Basisdatentypen mit Werten arbeiten und bei der Bearbeitung von Referenzdatentypen mit Adressen, wenn Referenztypattribute vorhanden sind die privaten Attribute der übergeordneten Klasse, dann wird es als öffentliches Attribut verwendet, wenn es von einer Unterklasse geerbt wird. Wenn also Unterklasse 1 dieses Attribut ausführt, wirkt es sich auf Unterklasse 2 aus.
s1.play.push(4) console.log(s1.play, s2.play) console.log(s1.__proto__ === s2.__proto__)//true console.log(s1.__proto__.__proto__ === s2.__proto__.__proto__)//true
Das Spielattribut in s1 ändert sich. Gleichzeitig ändert sich auch das Spielattribut in s2.
Wenn wir einer Unterklasse eine neue Methode hinzufügen oder eine Methode der übergeordneten Klasse überschreiben müssen, denken Sie daran, diese nach der Anweisung einzufügen, die den Prototyp ersetzt
function Person(name, age) { this.name = name, this.age = age } Person.prototype.setAge = function () { console.log("111") } function Student(price) { this.price = price this.setScore = function () { } } // Student.prototype.sayHello = function () { }//在这里写子类的原型方法和属性是无效的, //因为会改变原型的指向,所以应该放到重新指定之后 Student.prototype = new Person() Student.prototype.sayHello = function () { } var s1 = new Student(15000) console.log(s1)
Funktionen:
Nachteile:
ausgeführt werden und können nicht im Konstruktor Student.prototype = new Person()
ist:
Verwenden Sie einen universellen Aufruf () im Subtyp-Konstruktor, um den übergeordneten Typkonstruktor aufzurufen<script>
function Person(name, age) {
this.name = name,
this.age = age,
this.setName = function () {}
}
Person.prototype.setAge = function () {}
function Student(name, age, price) {
Person.call(this, name, age) // 相当于: this.Person(name, age)
/*this.name = name
this.age = age*/
this.price = price
}
var s1 = new Student('Tom', 20, 15000)</script>
Diese Methode implementiert nur eine teilweise Vererbung. Wenn der Prototyp der übergeordneten Klasse auch Methoden und Attribute hat, kann die Unterklasse diese Methoden und Attribute nicht erhalten.
console.log(s1.setAge())//Uncaught TypeError: s1.setAge is not a function
:
:
Der Schlüssel zu dieser Methode ist:
Erben Sie die übergeordnete Klasse, indem Sie die Klassenattribute des übergeordneten Klassenkonstruktors aufrufen, die Vorteile der Parameterübergabe beibehalten und dann die Instanz der übergeordneten Klasse als Prototyp der Unterklasse verwenden, um eine Wiederverwendung von Funktionen zu erreichen.优点: 可以继承实例属性/方法,也可以继承原型属性/方法 不存在引用属性共享问题 可传参 函数可复用 缺点: 调用了两次父类构造函数,生成了两份实例 方式四: 组合继承优化1 这种方式通过父类原型和子类原型指向同一对象,子类可以继承到父类的公有方法当做自己的公有方法,而且不会初始化两次实例方法/属性,避免的组合继承的缺点。 优点: 不会初始化两次实例方法/属性,避免的组合继承的缺点 缺点: 没办法辨别是实例是子类还是父类创造的,子类和父类的构造函数指向是同一个。 方式五: 组合继承优化2 借助原型可以基于已有的对象来创建对象, 同样的,Student继承了所有的Person原型对象的属性和方法。目前来说,最完美的继承方法!
方式六:ES6中class 的继承 ES6中引入了class关键字,class可以通过extends关键字实现继承,还可以通过static关键字定义类的静态方法,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。 需要注意的是,class关键字只是原型的语法糖,JavaScript继承仍然是基于原型实现的。 语法简单易懂,操作更方便 缺点: 并不是所有的浏览器都支持class关键字 function Person(name, age) {
this.name = name,
this.age = age,
this.setAge = function () { }
}
Person.prototype.setAge = function () {
console.log("111")
}
function Student(name, age, price) {
Person.call(this,name,age)
this.price = price
this.setScore = function () { }
}
Student.prototype = new Person()
Student.prototype.constructor = Student//组合继承也是需要修复构造函数指向的
Student.prototype.sayHello = function () { }
var s1 = new Student('Tom', 20, 15000)
var s2 = new Student('Jack', 22, 14000)
console.log(s1)
console.log(s1.constructor) //Student
console.log(p1.constructor) //Person
这种方式融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。不过也存在缺点就是无论在什么情况下,都会调用两次构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数的内部,子类型最终会包含父类型对象的全部实例属性,但我们不得不在调用子类构造函数时重写这些属性。
function Person(name, age) {
this.name = name,
this.age = age,
this.setAge = function () { }
}
Person.prototype.setAge = function () {
console.log("111")
}
function Student(name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () { }
}
Student.prototype = Person.prototype
Student.prototype.sayHello = function () { }
var s1 = new Student('Tom', 20, 15000)
console.log(s1)
但这种方式没办法辨别是对象是子类还是父类实例化console.log(s1 instanceof Student, s1 instanceof Person)//true true
console.log(s1.constructor)//Person
var B = Object.create(A)
以A对象为原型,生成了B对象。B继承了A的所有属性和方法。 function Person(name, age) {
this.name = name,
this.age = age
}
Person.prototype.setAge = function () {
console.log("111")
}
function Student(name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () {}
}
Student.prototype = Object.create(Person.prototype)//核心代码
Student.prototype.constructor = Student//核心代码
var s1 = new Student('Tom', 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
console.log(s1.constructor) //Student
console.log(s1)
class Person {
//调用类的构造方法
constructor(name, age) {
this.name = name
this.age = age
}
//定义一般的方法
showName() {
console.log("调用父类的方法")
console.log(this.name, this.age);
}
}
let p1 = new Person('kobe', 39)
console.log(p1)
//定义一个子类
class Student extends Person {
constructor(name, age, salary) {
super(name, age)//通过super调用父类的构造方法
this.salary = salary
}
showName() {//在子类自身定义方法
console.log("调用子类的方法")
console.log(this.name, this.age, this.salary);
}
}
let s1 = new Student('wade', 38, 1000000000)
console.log(s1)
s1.showName()
优点:
Das obige ist der detaillierte Inhalt vonWas sind die gängigen Vererbungsmethoden in js? (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!