iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 3
0
自我挑戰組

玩轉 React 從0到1系列 第 5

【Day 5】關於ES6從類別到繼承

  • 分享至 

  • xImage
  •  

前言

為什麽說 Class 是語法糖呢? 因為 Class 只是被包裝得好看的 Prototype-Based 而已

以類別為基礎(Class-Based) vs 以原型為基礎(Prototype-Based) OOP

Class-Based 像是 Java, C++:

  1. Class 定義了所有屬性,不可任意更動
  2. Instance 實現 Class

Prototype-Based 像是 Javascript:

  1. 只有 Object,任何 Object 在任何時候都可以指定或新增自己的屬性
  2. 任何 Object 可以以 prototype 形式跟其他 Object 關聯

那為什麼 ES6 要新增 Class ? 它只是為了提供更簡單的語法來創立物件跟繼承物件。

以下會用 ES5 跟 ES6 的語法分別來實作,這兩段的語法事實上是一樣的:

  • ES5:
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayHi = function() {
  console.log(`Hello My name is ${this.name} and I'm ${this.age} years old`);
}
var Jay = new Person('Jay', 23);
Jay.sayHi(); // Hello My name is Jay and I'm 23 years old.
  • ES6:
class PersonES6 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sayHi() {
        console.log(`Hello My name is ${this.name} and I'm ${this.age} years old`);
    }
}
var Jay = new PersonES6('Jay', 23);
Jay.sayHi(); // Hello My name is Jay and I'm 23 years old.

關於 ES6 的類別

  1. constructor

constructor 是類別的默認方法,就算沒有定義,也一樣會產生一個空的 constructor

class Person {}
// 等同於
class Person {
    constructor() {}
}
  1. class 必須使用 new,this 會指向此物件的實體
  2. getter 和 setter
    可以利用 get (getter:代表取得方法),與 set (setter: 代表設定方法)進行值的設定,一般用在私有變數多,這裡要注意,不會在 getter 中傳入變數,而 setter 也只會傳入一個變數。
class Square {
  constructor(width) {
    this.width = width;
    this.height = width;
  }
  get area() {
    return this.width*this.height;
  }
  set area(area) {
    this.width = Math.sqrt(area);
    this.height = Math.sqrt(area);
  }
}
let square1 = new Square(5);
console.log(square1); //{height: 5, width: 5}
console.log(square1.area); //25
square1.area = 4;
console.log(square1); //{height: 2, width: 2}
  1. 靜態方法

靜態方法(static)不會繼承或創立到物件上,只有原型才能使用,而且可以和 非靜態方法 重複命名。
這裡要注意,並沒有靜態屬性。

class Point {
    static getX() {
        console.log('get static X');
    }
    static getY(){
        console.log('get static Y');
    }
    getY(){
        console.log('get Y');
    }
}
let point = new Point();
Point.getX();  // "get static X"
point.getY();  // "get Y"

關於 ES6 的繼承

  1. extends 繼承

ES6 class 可以透過 extends 實現繼承,ES5 則是先創造實例(instance)的this,然後再將父母類別添加到this上面(父母類別.apply(this, parameters))

  1. super() 會去調用父母類別的 constructor
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
class ShapePoint extends Point {
  constructor(x, y, shape) {
    super(x, y); // 調用父母類別的 x, y
    this.shape = shape;
  }
}

如果子類別沒有定義 constructor,會默認添加 ...args

class ShapePoint extends Point{}
//等同於
class ShapePoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

實作 ES5 繼承機制

function Person(name,age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sendBasicInfo = function() {
  console.log(`My name is ${this.name} and ${this.age} years old.`);
}
function Student(name, age, school, classroom){
  Person.apply(this, [name, age]);
  this.school = school;
  this.classroom = classroom;
}
// 繼承 Person.prototype 物件方法
Student.prototype = Object.create(Person.prototype);
Student.prototype.studyHard = function() {
  console.log('I need to study hard');
}
var student1 = new Student('student1', 23, 'school', '1-1');
console.log(student1.sendBasicInfo()); // My name is student1 and 23 years old.
console.log(student1.studyHard()); // I need to study hard

實作 ES6 繼承機制

class Person{
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sendBasicInfo() {
    console.log(`My name is ${this.name} and ${this.age} years old.`);
  }
}
class Student extends Person{
  constructor(name, age, school, classroom){
    super(name, age, school);
    this.school = school;
    this.classroom = classroom;
  }
  studyHard() {
    console.log('I need to study hard');
  }
}
var student1 = new Student('student1', 23, 'school', '1-1');
console.log(student1.sendBasicInfo()); // My name is student1 and 23 years old.
console.log(student1.studyHard()); // I need to study hard

結論

  • 介紹了類別
  • 介紹了類別繼承的方式

/images/emoticon/emoticon70.gif明天是禮拜一啊,不想上班哈哈


上一篇
【Day 4】關於ES6原型與原型鏈
下一篇
【Day 6】關於ES6作用域
系列文
玩轉 React 從0到130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言