1. 程式人生 > 程式設計 >JavaScript ES6 Class類實現原理詳解

JavaScript ES6 Class類實現原理詳解

JavaScript ES6之前的還沒有Class類的概念,生成例項物件的傳統方法是通過建構函式。

例如:

function Mold(a,b){
         this.a=a;
         this.b=b;
     }
     Mold.prototype.count=function(){
       return this.a+this.b;
     };
     let sum=new Mold(1,2);
    console.log(sum.count())  //3

這中寫法跟傳統的面嚮物件語言差異較大,寫起來也比較繁雜。

ES6提供了更加接近其他語言的寫法,引入了Class(類)的概念,作為物件的模板,可以通過class關鍵字,定義類(類似python、java等);

當然ES6的大部分功能再ES5都能實現,ES6的class可以看作是一個語法糖,只是新的class定義類的寫法讓物件原型的寫法更加簡單明瞭、更接近與面向物件的程式設計思想。與上面ES5寫的類使用ES6實現,例如:

class Mold{
       constructor(a,b){
         this.a=a;
         this.b=b;
       }
       count(){
         return this.a+this.b;
       }
    }
    let sum=new Mold(1,2);
    console.log(sum.count())  //3

這裡ES6的類,只需用class定義,並且類的方法不需要用function定義;還有ES6的constructor方法,代表這該類的構造方法;並且它的this關鍵字指向著例項物件。這裡ES5的建構函式Mold,相當於ES6Mold類的constructor方法。

constructor

ES6例項物件的建構函式就是該類本身;並且當我們new 類名()就是執行了constructor這個函式。

例如:

class Mold{
       constructor(){
        console.log("aaa")
       }
    }
 let m=new Mold();// aaa
 console.log(m.constructor===Mold);//true

上面程式碼Mold類的constructor,例項化物件時執行預設constructor;

任何物件都有建構函式,並且建構函式與當前物件的類是相同;

例如:

let arr=new Array();
 console.log(arr.constructor===Array);//true
 let str=new String();
 console.log(str.constructor===String);//true
 let obj=new Object();
 console.log(obj.constructor===Object);//true

  2. 類的繼承 extends

繼承父類後,子類會繼承父類所有的方法和屬性(包括靜態方法和屬性)

如果子類沒有定義constructor方法,會預設被新增該方法

任何子類都有constructor方法;

例如:

//class 類名 extends 被繼承的類{}
Class Father{
   constructor(){
   }
   sum(){
     console.log("abc");
   }
   static fn(){
     console.log("hello")
   }
 }
 Class Son extends Father{
  
 }
 let s=new Son();
 s.sum()//abc,繼承了父類的sum()方法
 Son.fn()//hello 繼承了父類的靜態方法fn()

繼承後的子類方法的三種處理:

1). 完全繼承,不需要重寫這個方法,子類執行繼承方法內容與父類相同

2). 重寫覆蓋,只需要在這個類中重寫這個方法就可以覆蓋繼承過來的內容

3). 加工,子類可以用super呼叫父類的方法或屬性進行加工,再加上子類自己的方法和屬性

  3. super

呼叫父類的建構函式直接使用super(),並且可以傳參;

子類的建構函式中,只有呼叫了super之後才可以使用this關鍵字,否則會報錯;

例如:

//super.父類函式();
 class Father{
   constructor(){
    console.log("bbb");
   }
 }
 class Son extends Father{
   constructor(x){
    this.x=x;//ReferenceError,報錯
    super();
    this.x=x;//正確
   }
 }
 let sum=new Son();//bbb

  4. 類的static靜態

在屬性或方法前面使用 static定義類的靜態屬性和方法;

所有的靜態屬性和靜態方法都不能通過例項化的物件呼叫;

需要通過類來呼叫,靜態屬性和靜態方法是類的專屬屬性和方法,和例項化物件無關,比如陣列和數學方法中的:Array.from();Math.random()。

例如:

class Mold{
     static x=0;
     y=1;
     static fn1(){
       console.log("aaa")
     }
     fn2(){
       console.log("bbb");
     }
    }
   let m=new Mold();
   console.log(m.x,m.y);//undefined,1
   m.fn1(); // TypeError 
   m.fn2(); // bbb
   //需要通過類來呼叫
   Mold.fn1(); //aaa
   console.log(Mold.x);//0

靜態的使用場景:

一般靜態的方法是用來解決一系列該型別的方法;

解決具體型別的方法,不是解決某個具體物件的方法

靜態屬性,一般用於儲存該型別的一系列通用的屬性變數

這種儲存,在類建立的時候就已經變成全域性的了,可在任何地方呼叫,並且不會被自動銷燬

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。