1. 程式人生 > 實用技巧 >深入瞭解js的原型及原型鏈

深入瞭解js的原型及原型鏈

  對比c++&&java等基於類的語言,JavaScript常常令人困惑,因為其是動態的,本身不提供一個class的實現,(ES6中的關鍵字class只屬於一種語法糖,JavaScript仍然是基於原型的)。


  看完文章,應該掌握:

  1. __proto__
  2. prototype
  3. __proto__和prototype的關係
  4. 原型鏈的結構
  5. 原型物件的意義

首先了解什麼是原型?

  假設有一個物件cat,其建構函式為Animal

  1. 所有的引用型別(除了null)都有一個屬性__proto__,是一個物件,稱為隱式原型。(cat.__proto__)
  2. 引用型別的建構函式都有一個屬性prototype,是一個物件,成為顯式原型(Animal.prototype)
  3. 所有的引用型別的__proto__都指向其自身的建構函式的prototype屬性,也就是cat.__proto__ === Animal.prototype
  4. prototype,為原型物件,物件有一個屬性:constructor,即Animal.prototype.constructor === Animal
  5. prototype既然也是物件,那麼其自然也有其建構函式,因此也還會有自身的原型物件,即Animal.prototype
  6. 例項物件一旦建立,便會自動引用原型物件中的屬性和方法  

原型鏈是什麼?

    每個例項物件都有一個屬性__proto__,指向其建構函式的原型物件(prototype),該原型物件也有其原型物件(__proto__),層層向上,直到一個物件的原型物件為null,null沒有原型物件,作為原型鏈的最後一個環節。

    當試圖得到物件中的一個屬性時,假如物件中並不存在該屬性,那麼便會去它的原型物件中尋找,假如找不到,便會繼續向其原型物件的原型物件找,直到到了最上層的null為止。

    我認為:原型物件可以看作是建構函式的補充,建立的例項物件會擁有建構函式內的屬性和原型物件中屬性的引用

          

原型物件的意義?

  用於存放所有物件例項的共享資源,可以節省記憶體。

function Person(name,age){
    this.name = name;
    this.age = age;
    this.eat = function(){
        console.log(age + "歲的" + name + "在吃飯。");
    }
}
var p1 = new Person('xiaoming',18);
var p2 = new Person('xiaoli',17);
console.log(p1.eat === p2.eat);//輸出false

  也就是說我們創建出來的每一個物件,裡面都有獨立的eat方法,這樣將會佔用很多的資源。

function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.eat = function(){
        console.log(age + "歲的" + name + "在吃飯。");
}
var p1 = new Person('xiaoming',18);
var p2 = new Person('xiaoli',17);
console.log(p1.eat === p2.eat);//輸出true