zoukankan      html  css  js  c++  java
  • JS之class的前世今生

    Javascript之class的前世今生

    最早JavaScript中所谓的类,其实是一种设计模式:一个构造函数(consturctor)和一个用于在该类实例间共享属性和方法的原型对象(Objcet.prototype)的结合。为了达到继承,通过函数来模拟类来创建对象。

    今天我主要讲讲js类的发展,一是理清class的实质,二是掌握继承extends的实现,三是梳理ES6以前的关于这方面的知识。

    ES6 class的前世

    (1)创建对象

    js引入class的目的,其实就是为了创建对象,这里梳理一下ES6以前创建对象的方式。

    一、最基础的new

    var friend = new object();
    friend .name = "girl";
    friend .speak = function(){
        console.log(this.name + "_said:I miss you");
    }

    二、字面向量

    var friend = {
        name: 'girl',
        speak: function(){
            console.log(this.name + "_said:I miss you");
        }
    };

    方法一、二虽然可以创建对象,但是不易封装复用

    三、工厂模式

    function friend(name){
      var o = new object();
      o.name = name;
      o.speak = function(){
        console.log(this.name + "_said:I miss you");
      }
      return o;
    }
    
    var somebody = new friend("girl");
    somebody.speak();

    比起一二,friend函数确实是封装了一个属性和一个方法。然而有个问题,这个函数无法解决对象识别问题,就是创造出来的实例如somebody是Object类型,因为o是从Object里new出来的。

    四、构造函数

    function friend(name){
      this.name = name;
      this.speak = fucntion(){
        console.log(this.name + "_said:I miss you");
      }
    }
    var somebody = new friend("girl");
    somebody.speak();

    虽然这个方法解决了三的问题,但还是有缺陷。每次创建friend对象,每个对象都会有一个speak方法,消耗很大。

    五、原型封装

    function friend(name){
      this.name = name;
    }
    friend.prototype.speak = function(){
      console.log(this.name + "_said:I miss you");
    }
    
    var somebody = new friend("girl");
    somebody.speak();

    和构造函数不同的,这里通过原型封装的新对象的方法是所有实例都可以共享的。

    (2)继承

    现在已经能完成创建对象的要求了,但是类还有继承的要求。

    六、基于原型链的继承

     
    基于原型链的特点,通过将子类构造函数的原型作为父类构造函数的实例,这样就连通了子类-子类原型-父类,原型链的特点就是逐层查找,从子类开始一直往上直到所有对象的原型Object.prototype,找到属性方法之后就会停止查找,所以下层的属性方法会覆盖上层。

    方法一:

    function friend(name){
      this.name = name;
    }
    
    function girlFriend(name){}
    
    girlFriend.prototype = new friend(name);
    girlFriend.prototype.constructor = girlFriend;
    
    var a = new girlFriend("L");
    console.log(a.name);    //L

    1.把子类girlFriend的原型对象指向父类的实例化对象,这样即可以继承父类friend原型对象上的属性和方法 
    2.这时子类的constructor属性会指向friend,手动把constructor属性指向子类girlFriend,就可以在父类的基础上添加属性和方法了

    方法二:

    function friend(name){
      this.name = name;
    }
    
    function girlFriend(name){
      friend.call(this,name);
    }
    
    var a = new girlFriend("L");
    console.log(a.name);    //L

    ES6 class的今生

    class friend{
        constructor(name) {
            this.name = name; 
        }
    
        speak() {
            console.log(this.name + "_said:I miss you");
        }
    }
    
    class girlFriend extends friend {
        constructor(name) {     
            super(name);        //如果子类中存在构造函数,则需要在使用“this”之前首先调用super()
            this.name = name;
        }
    
        speak() {
            super.speak();  
        }
    }

    1.子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。 
    2.直接调用super(name),就可以直接继承父类的属性和方法

    可对比ES5的两种继承方法理解代码

  • 相关阅读:
    华为云文字识别服务关键技术、能力和产品落地需要注意的事宜(OCR系列二)
    【华为云技术分享】大数据容器化,头部玩家尝到了甜头
    【华为云技术分享】9 个Java 异常处理的规则!
    【华为云技术分享】一统江湖大前端DOClever—你的Postman有点Low
    【华为云技术分享】大前端的自动化工厂— babel
    非编程人学Python,要注意哪些隐秘的错误认知?
    【华为云技术分享】【一统江湖的大前端】PPT制作库impress.js
    【鲲鹏来了】鲲鹏迁移过程案例分享
    【华为云技术分享】圣诞特别版 | 数据库频频出现OOM问题该如何化解?
    HBuilder开发App
  • 原文地址:https://www.cnblogs.com/ZpandaZ/p/7397118.html
Copyright © 2011-2022 走看看