JS中的對象都包含了一個prototype的內(nèi)部屬性旨别,這個屬性所對應的就是該對象的原型。
1、原型分為顯式原型和隱式原型牢酵。顯示原型對應的是prototype屬性,隱式原型對應的是__proto__屬性衙猪。
2馍乙、所有對象(萬物皆對象)都有__proto__屬性,包括函數(shù)垫释、示例等丝格,只有函數(shù)才有prototype屬性。
3棵譬、prototype屬性值其實也是一個對象显蝌,類型為Object。它有一個自帶屬性constructor,這個constructor是一個指針茫船,指向函數(shù)本身琅束。比如 function Animal(){}。? ? Animal是一個函數(shù)指針算谈,可以叫函數(shù)對象涩禀。Animal.prototype是一個object對象。Animal.prototype.constructor == Animal然眼。
4艾船、一般情況下,一個實例的__proto__屬性等于實例的類型的原型高每。這句話比較抽象屿岂。舉個例子,var animal = new Animal()鲸匿,這里 animal.__proto__ = Animal.prototype爷怀。通俗的說法可以為,animal的原型為Animal.prototype带欢,但是這里其實涉及到顯式和隱式原型的概念运授,很容易用混烤惊。
5、如果訪問一個對象的屬性吁朦,其查找順序是柒室,先查找對象本身的屬性(可以理解為給this添加的屬性),然后查找實例的__proto__(即原型)中的屬性逗宜,在然后查找原型的__proto__里的屬性雄右,就這這樣一直查找下去,直到找到纺讲。最終找到的是Object.prototype.__proto__ 擂仍,它等于 null。 其實這個過程就是原型鏈熬甚。通俗點就是以__proto__屬性為媒介防楷,把對象相關的原型以鏈式方式串聯(lián)起來,以方便屬性和方法的訪問则涯。prototype就是要串的原型复局。可以把__proto__理解為線粟判,而prototype是珠子亿昏。
6、constructor屬性指向原型的構造方法档礁。其實這個屬性在示例new的過程中是沒有作用的角钩。在實例的instance of 方法也不是以它為依據(jù)的。后來我想到這個屬性有一個作用呻澜。比如递礼,我們有一個實例,但是無法獲取到實例的類(匿名自執(zhí)行函數(shù))羹幸,可以通過實例的constructor獲取到這個類脊髓,然后給類添加方法或屬性。不過這種使用方法好像也沒有什么必要栅受。只是為了加深理解将硝。
//constructor的作用,匿名自執(zhí)行函數(shù)場景屏镊。
var bydCar,ytCar ;
(function () {
function Car() {
}
bydCar = new Car();
ytCar= new Car();
})();
bydCar.constructor.prototype.name = 'BYD';
console.log("bydCar車的品牌:" + bydCar.name);
console.log("ytCar車的品牌:" + bydCar.name);
7依疼、new方法都做了哪些事情。這個還是以var animal = new Animal();為例而芥。
首先是 創(chuàng)建一個空對象律罢。?
然后把對象的__proto__屬性指向原型。
接下來棍丐,設置函數(shù)的this指向上邊的對象误辑,并執(zhí)行函數(shù)虫腋。
//new的過程。
var obj = {};
obj.__proto__ = Animal.prototype;
Animal.call(obj);//如果Animal中有return 就是把return結果作為new的對象稀余,否則就是上邊創(chuàng)建的obj對象。
原型鏈:原型鏈是是有一些用來繼承和共享屬性的對象組成的對象鏈趋翻。并且原型鏈的長度是有限的睛琳。
? 原型鏈的核心就是依賴對象的_proto_的指向,當自身不存在的屬性時踏烙,就一層層的扒出創(chuàng)建對象的構造函數(shù)师骗,直至到Object時,就沒有_proto_指向了讨惩。
最簡單的原型鏈分析
function Person(name){
this.name = name;
}
var p = new Person();
//p ---> Person.prototype --->Object.prototype---->null
屬性搜索原則:
? ? 1.當訪問一個對象的成員的時候辟癌,會現(xiàn)在自身找有沒有,如果找到直接使用。
? ? 2.如果沒有找到荐捻,則去原型鏈指向的對象的構造函數(shù)的prototype中找黍少,找到直接使用,沒找到就返回undifined或報錯处面。
原型繼承
//原型繼承的基本案例
function Person(name, age) {
this.name = name;
this.age = age;
}
//1.直接替換原型對象
var parent = {
sayHello : function() {
console.log("方式1:替換原型對象");
}
}
Person.prototype = parent;
var p = new Person("張三", 50);
p.sayHello();
//2.混入式原型繼承
console.log(".............混入式原型繼承..............");
function Student(name, age) {
this.name = name;
this.age = age;
}
var parent2 = {
sayHello : function() {
console.log("方式2:原型繼承之混入式加載成員");
}
}
for ( var k in parent2) {
Student.prototype[k] = parent2[k];
}
var p = new Student("張三", 50);
p.sayHello();