2017年8月29日 星期二

[JavaScript] Constructor, Prototype - Inheritance(3)

  • Inheritance (繼承)
    • 物件導向程式語言中,繼承分為兩種
      • interface inheritance (介面繼承):繼承函式的簽名
      • implementation inheritance (實作繼承):繼承實際的方法 (註:Javascript 只支援此)
    • Prototype Chaining
      • 利用 Prototype 搭配建構函式來實作繼承,稱為 Prototype Chaining
      • JavaScript 所有參考型別都是利用 Prototype Chaining 技術繼承 Object 型別
      • JavaScript 中每一個 Constructor 都有一個 Prototype 屬性,其中包含一個 Prototype 物件指回 Constructor
      • 將 Constructor  指向另一個物件型別,將取得此物件型別的 Prototype 與建構函式,形成 Prototype Chaining (如:[JavaScript] Constructor, Prototype (1) 與 [JavaScript] Constructor, Prototype - Object Literal Notation (2) 所使用的方法都為 Prototype Chaining)
var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    this.Name = Name;
    this.Age = Age;
    this.Authority = Authority;
}

AdministratorInfo.prototype = new UserInfo();
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 架構圖
      • Prototype Chaining 問題,當子物件實體建立時,無法傳引數到父建構函式
    • Constructor Stealing 技巧 (也稱做 object masquerading 或 classical inheritance)
      • 子建構函式中,使用 apply,call 或 bind 方法呼叫父建構函式,如此可將父建構函式定義的屬性繼承下來
      •  apply,call 或 bind
        1. 用來改變函數 this 對像的指向
        2. 第一個參數都為 this 指向的對像
        3. 第二個參數後為傳遞參數

var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    // Inherits parent's properties 
    // call
    UserInfo.call(this, Name, Age);
    // apply
    //UserInfo.apply(this, [Name, Age]);
    // bind
    //UserInfo.bind(this, Name, Age)();

    this.Authority = Authority;
}

AdministratorInfo.prototype = new UserInfo();
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 此方法的架構圖,發現父與子的結構中依然存在相同的 Name 與 Age
    • 使用 Object.create
      • 根據特定的 Prototype 來實做 Inheritance (繼承)
var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    // Inherits parent's properties 
    // call
    // 調用一個對象的一個方法,以另一个对象替换当前对象
    UserInfo.call(this, Name, Age);
    // apply
    //UserInfo.apply(this, [Name, Age]);
    // bind
    //UserInfo.bind(this, Name, Age)();

    this.Authority = Authority;
}

// Inherits methods
AdministratorInfo.prototype = Object.create(UserInfo.prototype);
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 架構圖,將 AdministratorInfo prototype 使用 Object.create 取代原本的 prototype
  • REF
    • 恆逸 - U2750c

沒有留言:

張貼留言