JavaScript原型與構造函數筆記

簡述

本文是筆者看完《JavaScript面向對象編程指南》後的一些理解與感悟,僅是對JavaScript原型多種繼承進行思路上的梳理,並不是講解基礎知識,適合瞭解原型和繼承,卻不夠清晰透徹的開發者。
但願各位開發者可以經過閱讀這篇文章縷清原型和構造函數的脈絡javascript

原型(prototype)

學習原型,你須要瞭解

  • 實例對象
  • 構造函數
  • 原型對象

觀察如下代碼java

function Person (){
    this.age = 20;
}
Person.prototype.gender = 'male';
var tom = new Person();    
tom.name = 'tom';
console.log(tom.name); // tom
console.log(tom.age); // 20
console.lot(tom.gender); // male
tom.constructor === Person; // true
tom.__proto__ === Person.prototype; // true

圖片描述

原型陷阱

function Dog(){
    this.tail = true;
}
var benji = new Dog();
var rusty = new Dog();
// 給原型添加方法
Dog.prototype.say = function(){
    return 'woof!';
}
benji.say(); // "woof!"
rusty.say(); // "woof!"
benji.constructor === Dog; // true
rusty.constructor === Dog; // true
// 此時,一切正常
Dog.prototype = {
    paws: 4,
    hair: true
}; // 徹底覆蓋
typeof benji.paws; // "undefined"
benji.say(); // "woof!"
typeof benji.__proto__.say; // "function"
typeof benji.__proto__.paws; // "undefined"
// 原型對象不能訪問原型的"新增屬性",但依然經過神祕的鏈接 __proto__ 與原有原型對象保持聯繫
// 新增實例
var lucy = new Dog();
lucy.say(); // TypeError: lucy.say is not a function 
lucy.paws; // 4
// 此時 __proto__ 指向了新的原型對象
// 因爲constructor是存儲在原型對象中的,因此新實例的constructor屬性就不能再保持正確了,此時它指向了Object()
lucy.constructor; // function Object(){[native code]}
// 舊實例的constructor仍是正確的
benji.constructor;
/* function Dog(){
    this.tail = true;
}*/
// 若想讓constructor正確,必須在新的原型對象中設置constructor屬性爲Dog
Dog.prototype.constructor = Dog;

原型總結

  • constructor屬性在Person.prototype對象中,即原型對象中。
  • __proto__屬性是在 tom(實例)new 的一瞬間創建的,指向原型對象即 Person.prototype
  • tom.constructor 等同於 tom.__proto__.constructor 訪問到的
  • __proto__屬性只能在學習或調試的環境下使用
  • 構造函數能夠當作一個規範,並不是實際存在的
  • var tom = new Person() 執行時,首先開闢一個新的地址空間用來建立並存放tom對象,再使Personthis指向tom對象而且執行Person函數。
  • 不要過度依賴constructor屬性,不可控。
相關文章
相關標籤/搜索