深入瞭解js的原型及原型鏈
阿新 • • 發佈:2020-08-05
對比c++&&java等基於類的語言,JavaScript常常令人困惑,因為其是動態的,本身不提供一個class的實現,(ES6中的關鍵字class只屬於一種語法糖,JavaScript仍然是基於原型的)。
看完文章,應該掌握:
- __proto__
- prototype
- __proto__和prototype的關係
- 原型鏈的結構
- 原型物件的意義
首先了解什麼是原型?
假設有一個物件cat,其建構函式為Animal
- 所有的引用型別(除了null)都有一個屬性__proto__,是一個物件,稱為隱式原型。(cat.__proto__)
- 引用型別的建構函式都有一個屬性prototype,是一個物件,成為顯式原型(Animal.prototype)
- 所有的引用型別的__proto__都指向其自身的建構函式的prototype屬性,也就是cat.__proto__ === Animal.prototype
- prototype,為原型物件,物件有一個屬性:constructor,即Animal.prototype.constructor === Animal
- prototype既然也是物件,那麼其自然也有其建構函式,因此也還會有自身的原型物件,即Animal.prototype
- 例項物件一旦建立,便會自動引用原型物件中的屬性和方法
原型鏈是什麼?
每個例項物件都有一個屬性__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