• 原型继承
    • 类的声明
      • 1.构造函数方式进行继承
      • 2.借助原型链实现继承
      • 3.组合方式
      • 4.组合方式改进1
      • 5.组合方式改进2
      • 6.原型式继承
      • 贴近实际开发原型链继承的例子
      • 写一个原型链继承的例子

    原型继承

    • 类与实例
      • 类的声明
      • 生成实例
    • 类与继承
      • 如何实现继承
      • 继承的几种方式

    类的声明

    • 类声明 构造函数
    1. function Animal1() {
    2. this.name = 'animal';
    3. }
    • ES6中class的声明
    1. class Animal2 {
    2. constructor() {
    3. this.name = 'animal';
    4. }
    5. }

    1.构造函数方式进行继承

    1. function Parent1() {
    2. this.name = 'parent1';
    3. }
    4. function Child1() {
    5. Parent1.call(this);
    6. this.type = 'child1';
    7. }
    8. console.log(new Child1());
    • 但是如果要继承原型对象上的方法是没办法继承的
    1. // 借助构造函数
    2. function Parent1() {
    3. this.name = 'parent1';
    4. }
    5. //
    6. Parent1.prototype.say = function () {
    7. console.log('say');
    8. }
    9. //但是如果要继承原型对象上的方法是没办法继承的
    10. function Child1() {
    11. Parent1.call(this);
    12. this.type = 'Child1';
    13. }
    14. console.log(new Child1());

    2.借助原型链实现继承

    1. function Parent2() {
    2. this.name = 'parent2';
    3. }
    4. function Child2() {
    5. this.type = 'child2';
    6. }
    7. Child2.prototype = new Parent2();//让child2的原型赋值为Parent2的实例
    8. console.log(new Child2());
    • s1与s2之间不相互隔离
    • 原型链中共用
    1. function Parent2() {
    2. this.name = 'parent2';
    3. this.num = [1,2,3];
    4. }
    5. function Child2() {
    6. this.type = 'child2';
    7. }
    8. Child2.prototype = new Parent2();//让child2的原型赋值为Parent2的实例
    9. var s1 = new Child2();
    10. var s2 = new Child2();
    11. console.log(s1.play,s2.play);

    3.组合方式

    1. function Parent3() {
    2. this.name = 'Parent3';
    3. this.play = [1,2,3];
    4. }
    5. function Child3() {
    6. Parent3.call(this);
    7. this.type = 'child3';
    8. }
    9. Child3.prototype = new Parent3();//Child3的原型对象指向Parent3的实例
    10. console.log(new child3);
    • 父类构造函数执行了多次,没有必要的重复执行

    4.组合方式改进1

    1. function Parent4() {
    2. this.name = 'parent4';
    3. }
    4. function Child4() {
    5. Parent4.call(this);
    6. this.type = 'child4';
    7. }
    8. Child4.prototype = Parent4.prototype;
    9. var s5 = new Child4();
    10. var s6 = new Child4();
    11. console.log(s5,s6);
    • instanceofconstructor
    1. console.log(s5 instanceof Child4,s5 instanceof Parent4);
    • 如何区分是子类实例化的还是父类实例化的

    5.组合方式改进2

    • 主要是在继承的时候让 子类的原型对象 =
      Object.Create(父类构造函数的原型对象)
    • 再通过改变子类的原型对象的constructor,因为此时的constructor的指向是父类原型对象的构造函数
    1. function Parent5() {
    2. this.name = 'Parent5';
    3. this.play = [1,2,3];
    4. }
    5. function Child5() {
    6. Parent5.call(this);
    7. this.type = 'Child5'
    8. }
    9. Child5.prototype = Object.create(Parent5.prototype);
    10. //通过Object.create()创建一个新的对象,传入的原型对象是Parent.prototype
    11. console.log('组合继承改进2',new Child5);
    12. //改变constructor的指向
    13. function Parent6() {
    14. this.name = 'Parent6';
    15. this.play = [1,2,3];
    16. }
    17. function Child6() {
    18. Parent6.call(this);
    19. this.type = 'Child6'
    20. }
    21. Child6.prototype = Object.create(Parent6.prototype);
    22. Child6.prototype.constructor = Child6;
    23. console.log('组合继承改进2-constructor',new Child6);

    6.原型式继承

    1. //原型式继承
    2. function object_oop(o) {
    3. function F() {
    4. }
    5. F.prototype = o;
    6. return new F();
    7. }
    8. var person = {
    9. name:"zhangjianan",
    10. friends:["yueyue","red"]
    11. };
    12. var OnePerson = object_oop(person);
    13. console.log('原型式继承',OnePerson);
    14. OnePerson.name = "Goge";
    15. console.log('原型式继承',OnePerson);
    16. var TwoPerson = object_oop(person);
    17. TwoPerson.friends.push("red");
    18. console.log('原型式继承',OnePerson,TwoPerson);
    19. //ES5原型式继承
    20. var ThreePerson = Object.create(person,{
    21. name: {
    22. value:"XIXI"
    23. }
    24. })
    25. console.log(ThreePerson);
    26. var FourPerson = Object.create(ThreePerson,{
    27. name:{
    28. value:[1,2,3,4]
    29. }
    30. })
    31. console.log('原型式继承',FourPerson);
    • ES5中主要使用Object.create()去创建对象

    贴近实际开发原型链继承的例子

    1. function Elem(id) {
    2. this.elem = document.getElementById(id);
    3. }
    4. Elem.prototype.html = function (val) {
    5. var elem = this.elem;
    6. if (val) {
    7. elem.innerHTML = val;
    8. return this; // 链式操作
    9. }else {
    10. return elem.innerHTML;
    11. }
    12. }
    13. Elem.prototype.on = function (type, fn) {
    14. var elem = this.elem ;
    15. elem.addEventListener(type, fn) ;
    16. }
    17. var div1 = new Elem('div1');
    18. //console.log(div1.html());
    19. div1.html('<p>tyrmars</p>
    20. ')
    21. div1.on('click',function () {
    22. alert('click')
    23. })

    写一个原型链继承的例子

    1. //动物
    2. function Animal(){
    3. this.eat = function () {
    4. console.log('animal eat');
    5. }
    6. }
    7. //狗?
    8. function Dog(){
    9. this.bark = function () {
    10. console.log('dog bark');
    11. }
    12. }
    13. Dog.prototype = new Animal();
    14. //哈士奇
    15. var hashiqi = new Dog();
    16. //如果要真正写,就要写更贴近实战的原型链
    • 推荐 阮一峰老师?‍?的两篇文章:

    Javascript 面向对象编程(一):封装

    Javascript继承机制的设计思想