1. 程式人生 > >Javascript原型、構造函數、實例的關系

Javascript原型、構造函數、實例的關系

eof isp 之間 asc http 分享 ava all 查看

1. 原型、構造函數、實例的關系

技術分享圖片

  1. 原型:
    • 原型通過constructor指向構造函數,原型如果是自定義對象且沒有明確將constructor指向構造函數,則原型的constructor指向函數的基類Function。
    • 原型通過方法isPrototypeOf檢查是否和實例之間有關系;
  2. 構造函數:
    • 構造函數的prototype指向原型
    • 因為構造函數和原型可以生成多個實例,所以它兩者不關心其所對應的實例,沒有直接獲取其對應實例的途徑。
  3. 實例
    • 實例的__proto__檢查指向其原型;
    • 實例的constructor檢查是否和構造函數有關系
    • 實例通過Object.getPrototypeOf(實例)
      可以查看其原型是誰
    • 實例和原型的constructor都明確的指向構造函數,但原型如果是自定義對象且沒有明確將constructor指向構造函數,則原型的constructor指向函數的基類Function。

2. 實例化的過程

  1. 創建一個對象
  2. 創建__proto__屬性指向構造函數的prototype屬性,創建constructor屬性指向自己的構造函數;
  3. 將構造函數的所有私有屬性方法復制到自己身上;
    以下為函數實現:

     function Move(name) {
         this.name = name
         this.say = function() {
             console.log('hello,say')
         }
     }
     Move.prototype.age = 23;
     let s  = new Move('tt');
     console.log(s);
    // new關鍵字的函數實現
     function newFunc(fn,...rest) {
         let obj = {};                            
         obj.constructor = fn;                 
         obj.__proto__ = fn.prototype;
         fn.call(obj,rest);                       
         return obj;
     }
    
     let newS = newFunc(Move, 'tt')
     console.log(newS) 

3. 擴展

對象兩兩不相等,因為他們指針所對應的實際存儲位置不一致,如果一致,也是相等的。

    function Move() {}
    let obj = {age: 23}
    Move.prototype = obj;
    var m = new Move()

    console.log(Move.prototype === m.__proto__)    // true
    console.log(Move.prototype === obj)            // true
    console.log(m.__proto__ === obj)               // true
    console.log(obj.isPrototypeOf(m))              // true
    console.log(Object.getPrototypeOf(m))          // { age: 23 }

Javascript原型、構造函數、實例的關系