// 先使用構(gòu)造函數(shù)創(chuàng)建一個對象:
function Person() {
}
var person = new Person();
person.name = 'Kevin';
console.log(person.name) // Kevin
// Person 就是一個構(gòu)造函數(shù)佩脊,我們使用 new 創(chuàng)建了一個實例對象 person埃难。
prototype
每個函數(shù)都有一個 prototype 屬性莱预,例Person.prototype军熏,函數(shù)的 prototype 屬性指向了一個對象度硝,這個對象正是調(diào)用該構(gòu)造函數(shù)而創(chuàng)建的實例的原型凌简。
Person.prototype.name = 'Kevin';等價于person.name = 'Kevin';
原型:每一個JavaScript對象(null除外)在創(chuàng)建的時候就會與之關(guān)聯(lián)另一個對象上炎,這個對象就是我們所說的原型,每一個對象都會從原型"繼承"屬性雏搂。
_ _ proto _ _
每一個JavaScript對象(除了 null )都具有的一個屬性藕施,叫_ _ proto_ _寇损,這個屬性會指向該對象的原型。例person._ _ proto_ _
function Person() {
}
var person = new Person();
//對象.__proto__ === 函數(shù).prototype
console.log(person.__proto__ === Person.prototype); // true
console.log(Person.prototype.constructor === Person) // true
實例與原型
當(dāng)讀取實例的屬性時裳食,如果找不到矛市,就會查找與對象關(guān)聯(lián)的原型中的屬性,如果還查不到诲祸,就去找原型的原型浊吏,一直找到最頂層為止。
function Person() {
}
Person.prototype.name = 'Kevin';
var person = new Person();
person.name = 'Daisy';
console.log(person.name) // Daisy
delete person.name;
console.log(person.name) // Kevin
給實例對象 person 添加了 name 屬性烦绳,當(dāng)我們打印 person.name 的時候卿捎,結(jié)果自然為 Daisy。當(dāng)我們刪除了 person 的 name 屬性時径密,讀取 person.name午阵,從 person 對象中找不到 name 屬性就會從 person 的原型也就是person._ _ proto_ _,也就是 Person.prototype中查找享扔,找到了 name 屬性底桂,結(jié)果為 Kevin。
原型鏈
JavaScript中所有的對象都是由它的原型對象繼承而來惧眠。而原型對象自身也是一個對象籽懦,它也有自己的原型對象,這樣層層上溯氛魁,就形成了一個類似鏈表的結(jié)構(gòu)暮顺,這就是原型鏈。
所有原型鏈的終點都是Object函數(shù)的prototype屬性秀存,因為在JavaScript中的對象都默認(rèn)由Object()構(gòu)造捶码。Objec.prototype指向的原型對象同樣擁有原型,不過它的原型是null或链,而null則沒有原型惫恼。
所以查找屬性的時候查到 Object.prototype 就可以停止查找了。
var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin
console.log(Object.prototype.__proto__ === null) // true