博客 / 詳情

返回

Class類,你真的瞭解嗎

image.png

定義

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,公共方法getYearsetYear。實例對象僅可以訪問公共成員,在類的內部可以訪問、修改私有屬於#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,公共屬性掛在實例對象上,靜態公共屬性、靜態公共方法在類的構造函數上,公共方法在原型鏈上。

經常有人説classfunction的語法糖,其實,隨着時間的推移,class關鍵字不僅僅是function語法糖,更具有新特性,如私有屬性、私有方法是function類不具備的,而且class定義的方法比function定義的方法優化了,去掉了function定義方式產生的prototype部分。


-

調用對象的屬性或方法時,我們都知道obj.nameobj['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中聲明。

圖片

喜歡可以關注微信公眾號“前端咖”
關注哦!優質原創文章在這裏等你哦!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.