定義
類class是面向對象程序設計實現信息封裝的基礎。類是一種用户定義的引用數據類型,也稱類類型。每個類包含數據説明和一組操作數據或傳遞信息的函數。類的實例稱為對象。
構成
類由類名、構造函數、屬性、方法組成。屬性、方法屬於成員,可以分為公共成員,保護成員、私有成員。
定義類
聲明一個僅有類名的類。
class Year{
constructor(){
}
}
// 簡寫
class Year{
}
公共屬性
公共屬性可以被實例對象訪問或修改,類的屬性默認是公共屬性。
class Year{
constructor(year){
this.year = year; // 公共屬性
}
}
let yearCs = new Year(2021);
console.log(yearCs.year); // 2021
私有屬性
私有屬性不可以被實例對象訪問,僅在類的內部訪問或修改,寫法是使用一個#作為前綴。
class Year{
constructor(year){
this.year = year;
}
#month = 1; // 私有屬性
}
let yearCs = new Year(2021);
console.log(yearCs['#month']); // undefined
靜態屬性
靜態屬性是使用關鍵字static聲明,將靜態屬性添加到類的構造函數中,用類本身訪問或修改。
class Year{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1; // 靜態屬性
}
let yearCs = new Year(2021);
console.log(Year.day); // 1
靜態私有屬性
靜態私有屬性是使用關鍵字static與#聲明,將靜態私有屬性添加到類的構造函數中,不能被用類本身訪問。
class Year{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1;
static #hour = 1; // 靜態私有屬性
}
console.log(Year['#hour']); // undefined
屬性對比
Class方式定義類與Function定義類的區別,想想輸出的內容,歡迎留言哦!
/**
* Class定義類
*/
class YearClass{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1;
static #hour = 1;
}
let yearCs = new YearClass(2021);
console.log(yearCs.year); // ???
console.log(yearCs['#month']); // ???
console.log(YearClass.day); // ???
console.log(YearClass['#hour']); // ???
/**
* Function 方式定義類
*/
function YearFunction(year){
this.year = year;
this['#month'] = 1;
}
YearFunction.day = 1;
YearFunction['#hour'] = 1;
let yearFn = new YearFunction(2021);
console.log(yearFn.year); // ???
console.log(yearFn['#month']); // ???
console.log(YearFunction.day); // ???
console.log(YearFunction['#hour']); // ???
Class
Function
公共方法
公共方法可以被實例對象調用。
class Year{
constructor(year){
this.year = year;
}
#month = 1;
getYear(){
return `今夕是何年${this.year},何月${this.#month}`;
}
setYear(year){
this.year = year;
this.#month = year%2;
}
}
let yearCs = new Year(2021);
console.log(yearCs.year, yearCs['#month']); // 2021 undefined
console.log(yearCs.getYear()); // 今夕是何年2021,何月1
yearCs.setYear(2022);
console.log(yearCs.getYear()); // 今夕是何年2022,何月0
定義類Year,包括公共屬性year、私有屬性#month,公共方法getYear、setYear。實例對象僅可以訪問公共成員,在類的內部可以訪問、修改私有屬於#month,可以保護類的內部數據,雖然,實例對象不能訪問私有成員,但是在實例對象的節點上是暴露相關信息。
私有方法
私有方法不可以被實例對象調用,寫法是使用一個#作為前綴。
class Year{
constructor(year){
this.year = year;
}
#month = 1;
getYear(){
return `今夕是何年${this.year}`;
}
#getMonth(){
return `今夕是何月${this.#month}`;
}
}
let yearCs = new Year(2021);
console.log(yearCs['getYear']()); // 今夕是何年2021
console.log(yearCs['#getMonth']()); // Uncaught TypeError: yearCs.#getMonth is not a function
公共方法可以被實例對象訪問,私有方法不可以被實例對象訪問,強制訪問會報錯哦。高能預警:公共方法getYear是在原型鏈上,私有方法#getMonth在實例上。
靜態方法
靜態方法是使用關鍵字static聲明,將靜態方法添加到類的構造函數中,用類本身調用。
class Year{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1;
getYear(){
return `今夕是何年${this.year}`;
}
#getMonth(){
return `今夕是何月${this.#month}`;
}
static getDay(){
return `今夕是何天${this.day}`;
}
}
let yearCs = new Year(2021);
console.log(Year.getDay()); // 今夕是何天1
靜態方法是通過類調用。靜態方法在類的構造函數上。
靜態私有方法
class Year{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1;
static #hour = 1;
getYear(){
return Year.#getHour();
}
#getMonth(){
return `今夕是何月${this.#month}`;
}
static getDay(){
return Year.#getHour();
}
static #getHour(){
return `今夕是何時${Year.#hour}`;
}
}
let yearCs = new Year(2021);
console.log(Year['#getHour']()); // Uncaught TypeError: Year.#getHour is not a function
console.log(Year.getDay()); // 今夕是何時1
console.log(yearCs.getDay()); // 今夕是何時1
靜態私有方法不能被類本身調用,但是,可以把靜態私有方法給公共方法或靜態公共方法內部調用。靜態私有方法在類的構造函數上。
方法對比
Class方式定義類與Function定義類的區別,想想輸出的內容,歡迎留言哦!
class YearClass{
constructor(year){
this.year = year;
}
#month = 1;
static day = 1;
static #hour = 1;
getYear(){
return `今夕是何年${this.year}`;
}
#getMonth(){
return `今夕是何月${this.#month}`;
}
static getDay(){
return `今夕是何天${Year.day}`;
}
static #getHour(){
return `今夕是何時${Year.#hour}`;
}
}
let yearCs = new YearClass(2021);
console.log(yearCs.getYear()); // ???
console.log(yearCs.#getMonth()); // ???
console.log(YearClass.getDay()); // ???
console.log(YearClass.#getHour()); // ???
function YearFunction(year){
this.year = year;
this.#month = 1;
}
YearFunction.day = 1;
YearFunction.#hour = 1;
YearFunction.prototype.getYear = function getYear(){
return `今夕是何年${this.year}`;
};
YearFunction.getDay = function getDay(){
return `今夕是何天${Year.day}`;
}
YearFunction.#getHour = function #getHour(){
return `今夕是何時${Year.#hour}`;
}
let yearFn = new YearFunction(2021);
console.log(yearFn.getYear()); // ???
console.log(YearFunction().getDay()); // ???
console.log(YearFunction().#getHour()); // ???
Class
Function
總結
關於Class,公共屬性、私有屬性、私有方法掛在實例對象上,靜態公共屬性、靜態私有屬性、靜態私有方法在類的構造函數上,公共方法在原型鏈上。
關於Function,公共屬性掛在實例對象上,靜態公共屬性、靜態公共方法在類的構造函數上,公共方法在原型鏈上。
經常有人説class是function的語法糖,其實,隨着時間的推移,class關鍵字不僅僅是function語法糖,更具有新特性,如私有屬性、私有方法是function類不具備的,而且class定義的方法比function定義的方法優化了,去掉了function定義方式產生的prototype部分。
附
-
調用對象的屬性或方法時,我們都知道obj.name與obj['name']是一樣的效果。今天給大家展示一個特列:
function YearFunction(year){
this.year = year; // 公共屬性
this['#month'] = 1; // 公共屬性
this.#month = 1; // Uncaught SyntaxError: Private field '#month' must be declared in an enclosing class
}
let yearFn = new YearFunction(2021);
語法錯誤:私有字段必需在類Class中聲明。
喜歡可以關注微信公眾號“前端咖”
關注哦!優質原創文章在這裏等你哦!