封装

  1. 构造函数可能会需要隐藏一些属性和方法不被外界轻易访问到,可以将这些属性和方法封装起来,然后通过一个外部可以调用的特定接口 (或者公共方法) 进行调用;
  2. 示例代码:
    function Person(name, age, sex) {
      this.name = name; // 公共属性
    
      var age = age;  // 私有属性
      var sex = sex;  // 私有属性
    
      // 外部访问此函数,暴露出私有属性
      this.show = function () {
        console.log(`${age}--${sex}`);
      }
    }
    
    var person = new Person("Bob", 21, "man");
    console.log(person.name);  // Bob
    console.log(person.age);   // undefined
    person.show();             // 21 -- man
    

继承:四大继承方案

原型继承

  1. 特点:

    1. 不像其他语言的继承一样 (其他语言的继承一般是拷贝继承,也就是子类会把父类中的属性和方法拷贝一份到子类中,供子类调用),原型继承是把父类的原型放到子类实例的原型链上,实例想调取这些方法,是基于 __proto__ 原型链查找机制完成的;
    2. 子类可以重写父类的方法 (这样会导致其他实例也收到影响)
    3. 父类中私有或公有的属性和方法都会变成子类中公有的属性和方法;
  2. 示例代码:

    function A(x) {
      this.x = x;
    }
    A.prototype.getX = function () {
      console.log(this.x);
    }
    
    function B(y) {
      this.y = y;
    }
    
    // 让父类 A 的属性和方法,在子类 B 实例的原型链上
    B.prototype = new A(200);
    B.prototype.constructor = B;
    
    B.prototype.getY = function () {
      console.log(this.y);
    }
    B.prototype.__proto__.sum = function () { }
    
    let b1 = new B(20);
    console.log(b1.y); // 20
    console.log(b1.getY()); // 20
    
  3. 图解

call 继承

  1. 特点:

    1. 只能继承私有的属性和方法 (因为把 Parent 当做普通函数执行,和其原型上的属性和方法没有关系),父类私有的变成子类私有的;
    2. 父类原型上的公有属性方法无法被继承过来;
  2. 示例代码:

    function A(x) {
      this.x = x;
    }
    A.prototype.getX = function () {
      return this.x;
    }
    
    function B(x, y) {
      // this 是 B 的实例 b1
      // b1.x = 200;
      A.call(this, x); // 因为把父类 A 当做普通函数执行,和其原型上的属性和方法没有关系
      this.y = y;
    }
    B.prototype.getY = function () {
      return this.y;
    }
    
    let b1 = new B(100, 200);
    console.log(b1.x); // 100
    console.log(b1.y); // 200
    console.log(b1.getX); // undefined (父类原型上的公有属性方法无法被继承过来)
    console.log(b1.getY()); // 200
    

寄生组合继承(call + 类似于原型继承)

  1. 特点

    1. call 继承实现:私有到私有;
    2. 原型继承实现:公有到公有;
  2. 示例代码:

    function A(x) {
      this.x = x;
    }
    A.prototype.getX = function () {
      return this.x;
    }
    
    function B(y) {
      // 继承 A 的私有属性和方法
      A.call(this, 200);
      this.y = y;
    }
    
    // Object.create 原理:
    // - 创建一个空函数 Fn 构造函数,Fn.prototype 指向 A.prototype
    // - 返回值是 new Fn 的实例对象
    B.prototype = Object.create(A.prototype);
    B.prototype.contructor = B;
    
    B.prototype.getY = function () {
      return this.y;
    }
    
    let b1 = new B();
    console.log(b1.x);
    console.log(b1.y);
    
  3. 图解

ES6 中 class 实现继承

  1. ES6 中基于 class 创建出来的类不能当做普通函数执行;

  2. 示例代码:

    class A {
      constructor(x) {
        this.x = x;
      }
      getX() {
        console.log(this.x);
      }
    }
    
    // extends 继承和寄生组合继承基本类似,「子类公有」继承「父类公有」
    // class Child extends Parent{} => B.prototype.__proto__ = A.prototype
    class B extends A {
      constructor(y) {
        // 子类只有继承了父类,才可以不写 constructor
        // 浏览器会默认自己创建 constructor(...args){super(...args)} 并执行
        // 但是一旦写了 constructor,必需要写 super() => A.call(this,200)
        super(200);
        this.y = y;
      }
    
      getY() {
        console.log(this.y);
      }
    }
    
    // B.__proto__ = Object.create(A.prototype);// 不允许重定向原型的指向
    let b1 = new B(200);
    console.log(b1);
    

多态:同一接口不同实现

  1. 就是在执行同一操作且作用于不同对象时,返回不同的结果,其实也就是把做什么和由谁去做分开,这样使得代码更容易维护,且条例清晰;

  2. 示例代码:

    function Animal() {
      this.bite = function () {
        console.log("animal bite!");
      }
    }
    
    function Cat() {
      this.bite = function () {
        console.log("Cat bite!");
      }
    }
    Cat.prototype = new Animal();
    
    function Dog() {
      this.bite = function () {
        console.log("Dog bite!");
      }
    }
    Dog.prototype = new Animal();
    
    function AnimalBite(animal) {
      if (animal instanceof Animal) //这 里是判断 animal 的原型是否指向 Animal
          animal.bite();
    }
    
    var cat = new Cat();
    var dog = new Dog();
    AnimalBite(cat); // Cat bite!
    AnimalBite(dog); // Dog bite!
    
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 封装
  2. 2. 继承:四大继承方案
    1. 2.1. 原型继承
    2. 2.2. call 继承
    3. 2.3. 寄生组合继承(call + 类似于原型继承)
    4. 2.4. ES6 中 class 实现继承
  3. 3. 多态:同一接口不同实现