繼承技巧
- 在 
JavaScript中繼承是指一個對象基於另一個對象 JavaScript是利用prototype來實現繼承以及來管理繼承。prototype對象用途是所有實例共享的屬性。- 所有對象默認繼承來自 
Object.prototype 
構造函數竊取繼承
我利用竊取方式來實現繼承,也就是在子類構造函數來竊取父類構造函數。
call/apply來調用父類構造函數,需要把this指向調用者。
function Person (name, age, role) {
  this.name = name;
  this.age = age;
  this.role = role;
}
Person.prototype.sayName = function () {
  console.log(`Hello, My name is ${this.name}`);
}
Person.prototype.role = function () {
  console.log(`I'm a ${this.role}`);
}
function Student (name, age, role) {
  Person.call(this, name, age, role)
}
// 使用 Object.create 會 return {} (如下)
// { constructor: Student } -> 對象.__proto__ 指向 Person.prototype
Student.prototype = Object.create(Person.prototype, {
  constructor: {
    configurable: true,
    enumerable: true,
    value: Student,
    writable: true
  }
})
const s = new Student('DecadeHew', 18, 'FrontEnd');
s.name // DecadeHew
s.sayName() // Hello, My name is DecadeHew
Object 繼承
- Object.create(prototype, defineProperty)
 - 帶給我們最簡潔建立 
prototypal inheritance 
const person = {
  type: 'Human',
  walk: true
}
const me = Object.create(person, { name: { value: 'DecadeHew' } });
// me 繼承了 person 裡所有屬性,也可以說 me 享有 person 權利。
// me 也繼承了 Object.prototype
me.name // DecadeHew 自有屬性
me.type // Human
// 以下會列出 prototype 關係圖
me.__proto__ === person
me.__proto__.__proto__ === Object.prototype
me.__proto__.__proto__.__proto__ === null // 完畢
Prototype chain 繼承
- 每個函數都有 prototype 屬性。
 - 每創建函數,就會同時創建它的 
prototype對象,prototype對象也會自動有constructor屬性。 prototype對象也是一個對象,它也有自己的prototype對象並繼承其屬性,這就是Prototype chain。(依上面程式:me對象繼承了Object.prototype,享有Object屬性和方法toString,keys…)
function Person (name, age, role) {
  this.name = name;
  this.age = age;
  this.role = role;
}
Person.prototype.sayName = function () {
  console.log(`Hello, My name is ${this.name}`);
}
Person.prototype.role = function () {
  console.log(`I'm a ${this.role}`);
}
function Student (name, age, role) {
  this.name = name;
  this.age = age;
  this.role = role;
}
// 為什麼我不寫 Student.prototype = Person.prototype;
// 因為 兩個構造函數的 prototype 都會指向同一個對象,
// 萬一我修改其中一個函數(Student)的 prototype,會影響另一個函數(Person)
Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.role = function () {
  console.log(`I'm a ${this.role}`);
}
const me = new Student('DecadeHew, 18)
me.name // DecadeHew
me.sayName() // Hello, My name is DecadeHew
// 以下會列出 prototype 關係圖
me.__proto__ === Student.prototype
me.__proto__.__proto__ === Person.prototype
me.__proto.__proto__.proto__ === Object.prototype
me.__proto.__proto__.proto__.__proto__ === null // 完畢
Object.prototype.__proto__ === null // 完畢
Student.prototype.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null // 完畢
// Function
Function.prototype.__proto__ === Object.prototype
Function.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
Student.__proto__ === Function.prototype
Student.__proto__.__proto__ === Object.prototype
Student.__proto__.__proto__.__proto__ === null // 完畢
Object.prototype.__proto__ === null // 完畢