js中实现继承的6种方式
- 作为一个合格的cv工程师,你可以不会,但我不允许你需要的时候找不到,收集一下继承的6种方式
原型链继承
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.price = price
}
var s1 = new Student('Tom', 20, 15000)
console.log(s1)
- 核心:拿父类实例来充当子类原型对象
- 缺点:
- 无法继承构造函数中的属性
- 创建子类实例时,无法向父类构造函数传参
- 对象中存在多余的属性
借用构造函数继承
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)
var s2 = new Student(14000)
console.log(s1, s2)
s1.play.push(4)
console.log(s1.setAge, s2.setAge)
console.log(s1.__proto__ === s2.__proto__)
console.log(s1.__proto__.__proto__ === s2.__proto__.__proto__)
console.log(s1.__proto__.__proto__.__proto__ === Object.prototype)
- 核心:借父类的构造函数来增强子类实例,相当于把父类的实例属性复制一份给子类实例
- call方法:父类构造函数.call(子类实例,参数一,参数二,参数三……)
- apply方法:父类构造函数.apply(子类实例,
[参数一,参数二,参数三……]
)
原型链+借用构造函数的组合继承
function Person(name, age) {
this.name = name,
this.age = age,
this.setAge = function () { }
}
Person.prototype.setAge = function () {
console.log("111")
}
var p1 = new Person('jack', 15)
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.constructor)
console.log(p1.constructor)
寄生组合继承法(完美版)
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)
console.log(s1.constructor)
- 属性:借用构造函数法call,apply,bind继承
- 方法:原型式继承
原型式继承(继承方法)
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)
console.log(s1.constructor)
console.log(s1)
- 核心:先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时构造函数的一个新实例
ES6 class继承
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)
this.salary = salary
}
showName() {
console.log("调用子类的方法")
console.log(this.name, this.age, this.salary);
}
}
let s1 = new Student('wade', 38, 1000000000)
let s2 = new Student('kobe', 40, 3000000000)
console.log(s1.showName === s2.showName)
console.log(s1)
s1.showName()