一、原型继承 //父类型 function Person() {} Person.prototype.setAge = function () {} //子类型 function Student() {} // 子类型的原型为父类型的一个实例对象 Student.prototype = new Person() //核心代码 优点: 1.父类新增原型方法/原型属性,子类都能访问到 2.简单,易于实现 缺点: 1.无法实现多继承 2.来自原型对象的所有属性被所有实例共享 3.创建子类实例时,无法向父类构造函数传参 4.要想为子类新增属性和方法,必须要在Student.prototype = new Person() 之后执行,不能放到构造器中 二、借用构造函数继承 function Person(name, age) {} Person.prototype.setAge = function () {} function Student(name, age, price) { Person.call(this, name, age) //核心代码,相当于: this.Person(name, age) } 优点: 1.解决了原型链继承中子类实例共享父类引用属性的问题 2.创建子类实例时,可以向父类传递参数 3.可以实现多继承(call多个父类对象) 缺点: 1.实例并不是父类的实例,只是子类的实例 2.只能继承父类的实例属性和方法,不能继承原型属性和方法 3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能 三、原型链+借用构造函数的组合继承 function Person (name, age) {} Person.prototype.setAge = function () {} function Student (name, age, price) { Person.call(this, name, age) } Student.prototype = new Person() //核心代码 //组合继承也是需要修复构造函数指向的 Student.prototype.constructor = Student //核心代码 优点: 1.可以继承实例属性/方法,也可以继承原型属性/方法 2.不存在引用属性共享问题 3.可传参 4.函数可复用 缺点: 1.调用了两次父类构造函数,生成了两份实例 四、组合继承优化1 function Person (name, age) {} Person.prototype.setAge = function () {} function Student (name, age, price) { Person.call(this, name, age) //核心代码 } Student.prototype = Person.prototype //优化关键 优点: 1.不会初始化两次实例方法/属性,避免的组合继承的缺点 缺点: 1.没办法辨别是实例是子类还是父类创造的,子类和父类的构造函数指向是同一个。 五、组合继承优化2(ES5最完美的继承方法) function Person (name, age) {} Person.prototype.setAge = function () {} function Student (name, age, price) { Person.call(this, name, age) //核心代码 } Student.prototype = Object.create(Person.prototype) //核心代码 Student.prototype.constructor = Student //核心代码 六、ES6中class 的继承 //定义一个父类 class Person { //调用类的构造方法 constructor(name, age) { this.name = name this.age = age } } //定义一个子类 class Student extends Person { constructor(name, age, salary) { super(name, age) //核心代码,调用父类的constructor(name, age) this.salary = salary } } 优点: 1.语法简单易懂,操作更方便 缺点: 1.并不是所有的浏览器都支持class关键字
转载于:https://www.cnblogs.com/zgdawdl/p/11496197.html