Johnson Mao

Day.29 「Class 語法糖~」 —— ES6 Class 構造函式

「Class 語法糖~」 —— ES6 Class 構造函式

ES6 新增了更接近傳統語言寫法的 Class 這個概念,基本上可以當作是一個語法糖,絕大部分的功能在 ES5 都可以做到,但 Class 可以讓構造函式的寫法更加清新!

什麼是語法糖? 就是新增的語法對原功能沒有什麼影響,主要是給程式開發者更方便的使用。

#class 初體驗

首先,我們先用之前的構造函式

複製成功!
function Person (name, gender) {
  this.name = name,
  this.gender = gender
}
Person.prototype.sayName = function(){     // 構造函式方法傳給原型鍊
  console.log( "大家好!我是" + this.name );
}

const person = new Person("毛毛", "男");
person.sayName();  // "大家好!我是毛毛"

接著來使用 class 構造函式,來看看差異,可以發現繼承方法可以寫在構造函式內,它會自動幫我們傳給原型鍊上,而物件資料寫在 constructor

複製成功!
class Person {
  // 構造函式方法,一定要使用 constructor 不能改名
  constructor (name, gender) {
    this.name = name;
    this.gender = gender;
  }
  
  sayName () {  // 添加方法必須使用這個語法
    console.log( "大家好!我是" + this.name ); 
  }
}

const person = new Person("毛毛", "男");
person.sayName();  // "大家好!我是毛毛"
console.log(person);
自動傳給繼承鍊上

#靜態屬性

我們都知道構造函式也是物件,ES6 以前構造函式要添加靜態屬性,就是使用物件的方法來添加,因為沒有使用到原型鍊,所以這個屬性是 Person 內的屬性,也就是靜態屬性

複製成功!
function Person(){}
Person.type = "人類";

const mao = new Person();
console.log(mao.type);     // undefined
console.log(Person.type);  // "人類"

#static 靜態方法

而 class 有新增靜態方法 static,來實現靜態屬性。

複製成功!
class Person(){
  static type = "人類";
}

const mao = new Person();
console.log(mao.type);     // undefined
console.log(Person.type);  // "人類"

#構造函式繼承

ES6 以前要寫構造函式繼承構造函式時

複製成功!
/*  父級構造函式,人  */
function Person (name, gender) {
  this.name = name,
  this.gender = gender
}
Person.prototype.sayName = function(){
  console.log( "大家好!我是" + this.name );
}

/*  子級構造函式,成年人  */
function AdultPerson (name, gender, age, married) {
  Person.call(this, name, gender);  // 透過 call 方法來繼承父級構造函式資料
  this.age = age;
  this.married = married;
}
/*  設定子級構造函式的原型  */
AdultPerson.prototype = new Person;
/*  校正子級構造函式的 constructor  */
AdultPerson.prototype.constructor = AdultPerson;

const mao = new AdultPerson("毛毛", "男", 27, "未婚");
mao.sayName(); // "大家好!我是毛毛"
console.log(mao);
子級構造函式繼承父級構造函式

可以看到使用子級構造函式,可以繼承父級構造函式的方法 sayName

#extends 繼承方法

而 class 有新增繼承方法 extendssuper,來實現繼承父級構造函式。

複製成功!
class Person {
  // 構造函式方法,一定要使用 constructor 不能改名
  constructor (name, gender) {
    this.name = name;
    this.gender = gender;
  }
  
  sayName () {  // 添加方法必須使用這個語法
    console.log( "大家好!我是" + this.name ); 
  }
}

class AdultPerson extends Person { // 使用 extends 繼承父級構造函式
  constructor (name, gender, age, married) {
    // 使用 super 調用父級構造函式的屬性方法
    super(name, gender);   // 與 Person.call(this, name, gender) 效果一樣
    this.age = age;
    this.married = married;
  }
  /*  可以自己新增方法  */
}

const mao = new AdultPerson("毛毛", "男", 27, "未婚");
mao.sayName(); // "大家好!我是毛毛"
console.log(mao);
子級構造函式繼承父級構造函式

使用起來,更簡潔有利~也更加直覺可以判斷是兩個構造函式與之間的關係!

#getter 與 setter

class 的 getset 方法, 在對某個屬性讀取時,會調用 get 對應的函式, 在對某個屬性設置時,會調用 set 對應的函式。

複製成功!
class Person {
  // 構造函式方法,一定要使用 constructor 不能改名
  constructor (name) {
    this.name = name;
  }
  get name () {
    console.log("名字被讀取");
  }
  set name (newVal) {
    console.log("名字被修改為" + newVal);
  }
}

const mao = new Person("毛毛");  // 這時會自動調 set name 方法,"名字被修改為毛毛"
console.log(mao.name);    // 這時會自動調 get name 方法,"名字被讀取"
mao.name = "鮭魚";  // 這時會自動調 set name 方法,"名字被修改為鮭魚"

#總結

Class 這個語法糖,讓我們寫構造函式會更加方便直觀,用過都說回不去了!

回首頁