原型链继承,将父类的实例作为子类的原型,他的特点是实例是子类的实例也是父类的实例,父类新增的原型方法/属性,子类都能够访问,并且原型链继承简单易于实现,缺点是来自原型对象的所有属性被所有实例共享,无法实现多继承,无法向父类构造函数传参。
构造继承,使用父类的构造函数来增强子类实例,即复制父类的实例属性给子类,构造继承可以向父类传递参数,可以实现多继承,通过call多个父类对象。但是构造继承只能继承父类的实例属性和方法,不能继承原型属性和方法,无法实现函数服用,每个子类都有父类实例函数的副本,影响性能
实例继承,为父类实例添加新特性,作为子类实例返回,实例继承的特点是不限制调用方法,不管是new 子类()还是子类()返回的对象具有相同的效果,缺点是实例是父类的实例,不是子类的实例,不支持多继承
拷贝继承:特点:支持多继承,缺点:效率较低,内存占用高(因为要拷贝父类的属性)无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
组合继承:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
寄生组合继承:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

1. 使用原型链的方法实现

  1. // 原型链继承
  2. function Person() {
  3. this.name = 'zs'
  4. this.age = 20
  5. }
  6. Person.prototype.getName = function () {
  7. return this.age
  8. }
  9. function Child() { }
  10. Child.prototype = new Person()
  11. let hd = new Child()
  12. console.dir(hd.getName());

2. 借用构造函数实现

  1. function Person(){
  2. this.name = 'zs'
  3. this.age = 20
  4. }
  5. function Child(){
  6. Person.call(this)
  7. }
  8. let hd = new Child()

3. 使用组合式方法实现继承

缺点是实现继承需要调用两次父类构造函数

  1. function Parent(name){
  2. this.name = name;
  3. this.colors = ['red', 'blue', 'green'];
  4. }
  5. Parent.prototype.getName = function(){
  6. console.log(this.name);
  7. }
  8. function Child(name,age){
  9. Parent.call(this,name);// 第二次调用 Parent()
  10. this.age = age;
  11. }
  12. Child.prototype = new Parent(); // 第一次调用 Parent(

4. 原型式继承

  1. // 原型式继承 使用Object.create方法重新创建一个对象实现
  2. // 包含引用类型的属性值始终都会共享相应的值, 这点跟原型链继承一样
  3. function objectCreate(obj) {
  4. function fn() { }
  5. fn.prototype = obj
  6. return new fn()
  7. }
  8. let person = {
  9. name: 'zs', age: 20
  10. }
  11. let hd = objectCreate(person) // 手写实现Object.create
  12. let ob = Object.create(person) // es6出现的
  13. console.log(hd.name);
  14. console.log(ob.name);

5. 使用函数方法继承

跟构造函数一样 使用前 每次创建对象时都需要在创建一次对象

  1. function createObj(obj) {
  2. let newobj = Object.create(obj)
  3. newobj.view = function () {
  4. this.name = 'zs'
  5. this.age = 20
  6. return this.name
  7. }
  8. return newobj
  9. }
  10. let o = {
  11. name: 'ls', age: 21
  12. }
  13. let hd = createObj(o)
  14. console.dir(hd.view());

6. 寄生组合式继承

  1. // 实现一个继承的方法 extend
  2. function _extend(child, parent) {
  3. child.prototype = Object.create(parent.prototype)
  4. Object.defineProperty(child.prototype, 'constructor', {
  5. value: child,
  6. enumerable: false
  7. })
  8. }
  9. function User() {
  10. this.name = 'user'
  11. this.view = function () {
  12. return this.name
  13. }
  14. }
  15. function Admin() {
  16. this.name = 'admin'
  17. this.view = function () {
  18. // this.name = 'admin'
  19. return this.name
  20. }
  21. }
  22. Admin.prototype.getAdmin = function () {
  23. this.age = 21
  24. this.name = 'admin'
  25. return this.age
  26. }
  27. _extend(User, Admin)
  28. let dh = new User()
  29. console.dir(dh.getAdmin()); // 21
  30. console.dir(dh.name); // admin
  31. console.dir(dh); // User

7. es6语法extends

  1. class Child extends Parent{}