Javascript原型鏈梳理
先來個簡單的代碼:
function Info(name, age){
this.name = name;
this.age = age;
this.message = function () {
console.log(this.name + "is" + this.age + "year‘s old");
}
}
var lynn = new Info("Lynn", 20);
構造函數的首字母一般大寫,用來區分於普通函數,使用 new 調用,沒有返回值,得到的對象成為該函數的一個實例。
構造函數的prototype屬性,稱為原型屬性,是一個隱藏屬性,指向一個是object類型,稱為原型對象。
構造函數原型對象的 constructor 屬性 始終指向構造函數本身。
fn.prototype.constructor === fn;
- 對於所有的對象,都有proto屬性,這個屬性對應該對象的原型
- 對於函數對象,除了proto屬性之外,還有prototype屬性,當一個函數被用作構造函數來創建實例時,該函數的prototype屬性值將被作為原型賦值給所有對象實例(也就是設置實例的proto屬性)
當一個函數被用作構造函數來創建實例時,該函數的prototype屬性值將被作為原型賦值給所有對象實例(也就是設置實例的proto屬性),也就是說,所有實例的原型引用的是函數的prototype屬性。
lynn.proto ===Info.prototype
在構造函數的原型上面附加的屬性或者方法, 可以被其所有的實例共用.
當代碼獲取某個對象的屬性時,首先會在對象實例本身內查找,如果查找不到,就會向上搜索其原型對象。為實例添加一個屬性時,這個屬性會屏蔽原型對象中的 同名屬性。若想訪問原型對象中的屬性值,需要使用delete將這個同名屬性在實例中徹底刪除。(註意:使用delete刪除構造函數中的屬性將把實例的原型對象中的屬性也刪除即如果把name放在Person()中,使用delete,person2的name將不存在)
function Info() {};
Person.prototype.name = ‘Lily‘;
Person.prototype.age = 18;
var info1 = new Info();
var info2 = new Info();
info2.name = "Tom";
console.log(info1.name);// Lily
console.log(info2.name); // Tom
delete.info2.name;
console.log(info2.name); // Lily
一個屬性能夠訪問時(無論是在實例還是原型對象中)in操作符都會返回true,所以當in操作符返回true。hasOwnProperty("屬性名")可以檢測一個屬性是存在於實例還是原型對象中,其返回值true代表存在於實例中,false代表存在於原型對象中。
原型對象本身同樣擁有一個內部屬性 [[prototype]], 指向當前構造函數的構造函數的原型對象.
這種由原型對象構建而成的鏈表, 就是原型鏈.
原型鏈存在的意義, 在於盡可能的共用方法和屬性. 或者其他更多的我不知道的意義.
在JavaScript語言中,所有對象的原型鏈根節點都是Object.prototype。Object.prototype值是無法修改,它提供了一些默認的方法。且它的proto等於null!
instanceof是一個二元運算符,如:A instanceof B. 其中,A必須是一個合法的JavaScript對象,B必須是一個合法的JavaScript函數 (function). 判斷過程如下:
如果函數B在對象A的原型鏈 (prototype chain) 中被發現,那麽instanceof操作符將返回true,否則返回false.
所以導致了:
Function instanceof Object; //true
Object instanceof Function; //true
Function instanceof Function; //true
Object instanceof Object; //true
這樣的情況發生!
Javascript原型鏈梳理