class在es6中本質是什麼

2022-10-28 22:01:03

class在es6中本質是函數(構造器),使用的時候,也是直接對類使用new命令,跟建構函式的用法一致;class可以看作一個語法糖,讓物件原型的寫法更加清晰、更像物件導向程式設計的語法。用class定義類的方法「class Person{//類宣告}」或「const Person=class{//類表示式}」。

前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

es6的Class類詳解

class基本語法

JavaScript 語言中,生成範例物件的傳統方法是通過建構函式和原型的組合模式.ES6 提供了更接近傳統語言(java)的寫法,引入了 Class(類)這個概念,作為物件的模板。通過class關鍵字,可以定義類。

class point{ 
   
	constructor(x,y){ 
   
        this.x=x;
        this.y=y;
    }
    play(){ 
   
        console.log("我會玩");
    }
}
登入後複製

ES6 的class可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的class寫法只是讓物件原型的寫法更加清晰、更像物件導向程式設計的語法而已。

注:「語法糖」:是由英國電腦科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指計算機語言中新增的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式設計師使用。

class在ES6本質就是函數(構造器)

1.png

class中的原型方法全部被新增到了parent的原型物件上

2.png

ES6 的class與ES5寫法的幾個核心注意點: ES5 的建構函式Point,對應 ES6 的Point類的構造方法。 類的所有方法都定義在類的prototype屬性上面。 定義「類」的方法的時候,前面不需要加上function這個關鍵字,直接把函數定義放進去了就可以了 方法之間不需要逗號分隔,加了會報錯 ES6的class使用方法與ES5的建構函式一模一樣

//類的所有方法都定義在類的prototype屬性上面。
class piont{ 
   
    constructor(){ 
   
		//
    }
    play(){ 
   
        
    }
}
//上述程式碼等價於
point.prototype={ 
   
    constructor() { 
   },
    play(){ 
   };
}

//在類的範例上面呼叫方法,其實就是呼叫原型上的方法。
class Ba{ 
   
	//
}
let b=new Ba();
b.constructor===Ba.prototype.constructor//true
登入後複製

另外:ES5 的建構函式Point,對應 ES6 的Point類的構造方法。

由於類的方法都定義在prototype物件上面,所以類的新方法可以新增在prototype物件上面。Object.assign方法可以很方便地一次向類新增多個方法。

class ponit{ 
   
    constructor(){ 
   
        
    }
}
Object.assign(Point.prototype,{ 
   
	play(){ 
   };
})
//Class直接定義的方法之間不需要逗號分隔,加了會報錯. 但是這裡是Object.assign的方法格式, 這裡面需要往Point.prototype裡面新增的方法就需要符合物件的預設格式
登入後複製

類的內部所有定義的方法,都是不可列舉的(non-enumerable)。通過Object.assign方法往類的原型上新增的方法,constructor不可列舉, 其他的可以列舉

Class的基本語法之constructor

constructor方法是類的預設方法,通過new命令生成物件範例時,自動呼叫該方法。一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被預設新增。

constructor方法預設返回範例物件(即this),完全可以指定返回另外一個物件 (得是在創造class時就定義設定的, 在創造完class後,通過Object.assign的方式是沒法改變建構函式的返回值的).

Class的基本語法之類的呼叫方式

類必須使用new呼叫,否則會報錯。這是它跟普通建構函式 ( 普通建構函式完全可以當做普通函數使用 ) 的一個主要區別,後者不用new也可以執行。

3.png

Class的基本語法之getter和setter

與 ES5 一樣,在「類」的內部可以使用get和set關鍵字,對某個屬性設定存值函數和取值函數,攔截該屬性的存取行為。

  class demo{ 
   
            constructor(age){ 
   
                this.age=agie;
                this._age=age;
            }
            get age(){ 
   
                return this._age;
            }
            set age(value){ 
   
                this._age=value;
                console.log("年齡"+value);
            }
        }
        let kevin=new demo(9);
        kevin.age=18;
        console.log(kevin.age);
登入後複製
Class的基本語法之類的屬性名

4.png

上面程式碼中,Square類的方法名getArea,是從表示式得到的。

Class的基本語法的特別注意點

(1)嚴格模式

類和模組的內部,預設就是嚴格模式,所以不需要使用use strict指定執行模式。只要你的程式碼寫在類或模組之中,就只有嚴格模式可用。考慮到未來所有的程式碼,其實都是執行在模組之中,所以 ES6 實際上把整個語言升級到了嚴格模式。

(2)不存在提升

new foo();
class foo{};
登入後複製

上面程式碼中,Foo類使用在前,定義在後,這樣會報錯,因為 ES6 不會把類的宣告提升到程式碼頭部。

(3)name 屬性

class point{
}
point.name//point
登入後複製

由於本質上,ES6 的類只是 ES5 的建構函式的一層包裝,所以函數的許多特性都被Class繼承,包括name屬性。

(4)this 的指向

類的方法內部如果含有this,它預設指向類的範例。但是,必須非常小心,一旦單獨使用該方法,很可能報錯。

5.png

printName方法中的this,預設指向Logger類的範例。但是,如果將這個方法提取出來單獨使用,this會指向該方法執行時所在的環境(由於 class 內部是嚴格模式,所以 this 實際指向的是undefined),從而導致找不到print方法而報錯。

解決辦法:

一個比較簡單的解決方法是,在構造方法中繫結this,這樣就不會找不到print方法了。

另一種解決方法是使用箭頭函數。箭頭函數位於建構函式內部,它的定義生效的時候,是在建構函式執行的時候。這時,箭頭函數所在的執行環境,肯定是範例物件,所以this會總是指向範例物件。

class Logger{ 
   
    constructor(){ 
   
        this.printName=this.printName.bind(this);
        //但是請注意bind之後返回的函數裡面的this就永久鎖死了問題:!!! !!! 堅決別用 
    }
}
//箭頭函數
class Obj{ 
   
    constructor(){ 
   
        this.getThis=()=>this;
    }
}
let o=new Obj();
o.getThis()===o//true
登入後複製

Class的靜態屬性和方法

類相當於範例的原型,所有在類中定義的方法,都會被範例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被範例繼承,而是直接通過類來呼叫,這就稱為「靜態方法」。

 class Person{ 
   
            static sum=0;
            constructor(){ 
   
                this.add();
            }
            add(){ 
   
                Person.sum++;
            }
        }
        let kaiwen=new Person();
        console.log("當前的聊天室人數為:"+Person.sum);
        //作用:當沒有範例化的時候,我們可以通過靜態的屬性和方法去獲取一些資訊
 // 注意,如果靜態方法包含this關鍵字,這個this指的是類,而不是範例。靜態方法可以與非靜態方法重名。
登入後複製

父類別的靜態方法,可以被子類繼承靜態方法也是可以從super物件上呼叫的。

 class Person{ 
   
            constructor(name){ 
   
                this.name=name;
                this.sex="男";
            }
        }
        class Student extends Person{ 
   
            constructor(name,age){ 
   
                super(name);
                this.age=age;
            }
        }
        let s=new Student("張三",11);
        console.log(s.name);
        console.log(s.age);
        console.log(s.sex);
登入後複製

Class的私有方法和私有屬性

私有方法和私有屬性:是隻能在類的內部存取的方法和屬性,外部不能存取。 這是常見需求,有利於程式碼的封裝,但 ES6 不提供,只能通過變通方法模擬實現。

_bar方法前面的下劃線,表示這是一個只限於內部使用的私有方法。但是,這種命名是不保險的,在類的外部,還是可以呼叫到這個方法

下面程式碼中的寫法不僅可以寫私有屬性,還可以用來寫私有方法

 class Cat{ 
   
            #eyes="眼睛";
            static pai(){ 
   
                console.log("凱文");
            }
            say(){ 
   
                Cat.pai();
                console.log("貓有一雙大大的"+this.#eyes);
            }
        }
        let kate=new Cat();
        kate.say();
登入後複製

私有屬性也可以設定 getter 和 setter 方法。

私有屬性不限於從this參照,只要是在類的內部,範例也可以參照私有屬性。

建構函式的新屬性

ES6 為new命令引入了一個new.target屬性,該屬性一般用在建構函式之中,返回new命令作用於的那個建構函式。如果建構函式不是通過new命令呼叫的,new.target會返回undefined,因此這個屬性可以用來確定建構函式是怎麼呼叫的。

私有屬性也可以設定 getter 和 setter 方法。

私有屬性不限於從this參照,只要是在類的內部,範例也可以參照私有屬性。

建構函式的新屬性

ES6 為new命令引入了一個new.target屬性,該屬性一般用在建構函式之中,返回new命令作用於的那個建構函式。如果建構函式不是通過new命令呼叫的,new.target會返回undefined,因此這個屬性可以用來確定建構函式是怎麼呼叫的。

6.png

【相關推薦:、】

以上就是class在es6中本質是什麼的詳細內容,更多請關注TW511.COM其它相關文章!