可視化網(wǎng)站制作軟件站長(zhǎng)之家ppt素材
1.prototype解釋
在JavaScript中,prototype對(duì)象是實(shí)現(xiàn)面向?qū)ο蟮囊粋€(gè)重要機(jī)制。
每個(gè)函數(shù)就是一個(gè)對(duì)象(Function),函數(shù)對(duì)象都有一個(gè)子對(duì)象 prototype對(duì)象,類是以函數(shù)的形式來定義的。prototype表示該函數(shù)的原型,也表示一個(gè)類的成員的集合。
在通過new創(chuàng)建一個(gè)類的實(shí)例對(duì)象的時(shí)候,prototype對(duì)象的成員都成為實(shí)例化對(duì)象的成員。
1、該對(duì)象被類所引用,只有函數(shù)對(duì)象才可引用;
2、在new實(shí)例化后,其成員被實(shí)例化,實(shí)例對(duì)象方可調(diào)用。
同時(shí),函數(shù)是一個(gè)對(duì)象,函數(shù)對(duì)象若直接聲明成員,不用被實(shí)例化即可調(diào)用。
上面兩點(diǎn)很重要,第一點(diǎn)(該對(duì)象被類所引用,只有函數(shù)對(duì)象才可引用): 只有當(dāng)一個(gè)對(duì)象被定義為函數(shù)對(duì)象時(shí),才擁有對(duì)prototype對(duì)象引用的prototype屬性,這點(diǎn)必須知道,因?yàn)檫@牽涉到了new一個(gè)對(duì)象的過程中js引擎要完成對(duì)prototype進(jìn)行一系列操作,而普通的js對(duì)象由于并不能被new,即使擁有prototype也是無意義的;第二點(diǎn)在我之前的文章中已討論過( 改變this的引用,為實(shí)例對(duì)象直接定義成員屬性),所以若直接在函數(shù)對(duì)象中聲明成員,無法被實(shí)例對(duì)象訪問。
2.prototype作用
上面說了prototype的一些定義,那么prototype有什么作用。上一段落中其中解釋了prototype的作用,“ 通過new創(chuàng)建一個(gè)類的實(shí)例對(duì)象時(shí),prototype對(duì)象的成員都成為實(shí)例化對(duì)象的成員”,意思就是我們可以為new創(chuàng)建的實(shí)例對(duì)象動(dòng)態(tài)添加成員變量,而無需在函數(shù)對(duì)象中定義所有的屬性和方法。如下代碼:
function animal(){}animal.prototype.name = "animal";
animal.prototype.move = function(){alert("i can move");
}var animalObj = new animal();
alert(animalObj.name);
animalObj.move();
運(yùn)行結(jié)果:


通過new創(chuàng)建一個(gè)函數(shù)對(duì)象的實(shí)例對(duì)象時(shí),該函數(shù)對(duì)象的prototype原型對(duì)象的成員都能被實(shí)例對(duì)象訪問。之前在我的前一篇文章中《 js中this關(guān)鍵字探討》就模擬了一下new一個(gè)對(duì)象的過程,但是當(dāng)時(shí)我們并沒有涉及到prototype對(duì)象,那么涉及到了prototype對(duì)象,這個(gè)過程又到底是怎么實(shí)現(xiàn)的呢?
3.new過程中對(duì)prototype對(duì)象的操作
一個(gè)函數(shù)對(duì)象被new實(shí)例化成為實(shí)例對(duì)象時(shí),可以分解為以下三步(用上面的animal對(duì)象作為例子):
第一步:定義animalObj = {};
第二步:animalObj?.__proto__ = animal.prototype;
第三步:animal.call(animalObj?);
OK,這里需要解釋一下__proto__: 每個(gè)對(duì)象都在其內(nèi)部初始化一個(gè)屬性,就是__proto__,當(dāng)訪問一個(gè)對(duì)象屬性時(shí),如果內(nèi)部不存在這,就會(huì)去__proto__里找,__proto__又會(huì)有自己的__proto__,于是一直找下去,這就是原型鏈的概念。
當(dāng)訪問animalObj 的name和move屬性時(shí),animalObj并沒有這些屬性,就會(huì)去__proto__中找,在第二步中,__proto__指向了animal.prototype,所以animal.prototype定義了name和move屬性,所以就可以訪問這些屬性。那么到底怎么驗(yàn)證我們對(duì)于__proto__的結(jié)論呢?
按照標(biāo)準(zhǔn)__proto__不對(duì)外公開,是個(gè)私有屬性,但chrome的引擎將其暴露出來成一個(gè)共有的屬性,可對(duì)外訪問和設(shè)置,IE不能直接訪問,如下:
alert(animalObj.__proto__ === animal.prototype);
運(yùn)行結(jié)果:

總結(jié):當(dāng)一個(gè)函數(shù)對(duì)象被被new為一個(gè)實(shí)例對(duì)象時(shí),函數(shù)對(duì)象的prototype對(duì)象中的屬性并沒有直接成為實(shí)例對(duì)象的成員屬性,而是成為實(shí)例對(duì)象的__proto__對(duì)象中的屬性,而函數(shù)對(duì)象中的成員(需要使用this關(guān)鍵字)會(huì)被改變引用直接成為實(shí)例對(duì)象的成員屬性
4.prototype擴(kuò)展:實(shí)現(xiàn)js對(duì)象的繼承
上面說到,當(dāng)訪問一個(gè)對(duì)象的成員屬性時(shí),如果對(duì)象本身沒有該屬性時(shí),會(huì)去它的__proto__對(duì)象中找,如果找不到,繼續(xù)找__proto__的__proto__對(duì)象中的屬性,一直往下找??梢岳眠@一特性,實(shí)現(xiàn)類似于java中的繼承,如下代碼:
// 動(dòng)物"類"(構(gòu)造函數(shù))
function animal(){}animal.prototype.name = "animal";
animal.prototype.move = function(){alert("i can move");
}// 定義一個(gè)cat對(duì)象,繼承animal中的成員
function cat(){}//prototype實(shí)現(xiàn)繼承
cat.prototype = new animal();// 為cat.prototype增加成員
cat.prototype.detail = "I am a cat , I am also an animal";// cat的實(shí)例對(duì)象,訪問成員屬性
var c = new cat();
alert(c.detail);
alert(c.name);
c.move();
運(yùn)行結(jié)果:



過程拆分:
1.var a = new animal(); 得出a.__proto__ = animal.prototype
2.cat.prototype = a,cat.prototype.__proto__ = a.__proto__
3.var c = new cat(),得出c.__proto__ = cat.prototype,所以c.__proto__.__proto__ = animal.prototype;
所以,當(dāng)訪問c的detail時(shí),本身找不到該屬性,會(huì)找__proto__(即cat.prototype)中是否有該屬性,找到了該屬性,同理,訪問name和move屬性時(shí),會(huì)繼續(xù)往下遍歷__proto__中是否有該屬性。
這也就是原型鏈的實(shí)現(xiàn)原理。本質(zhì)上prototype只是一個(gè)假象,在實(shí)現(xiàn)原型鏈中只起到輔助作用,只是在new的時(shí)候有價(jià)值,原型鏈的本質(zhì),其實(shí)在于__proto__
👉👉👉 自己搭建的租房網(wǎng)站:全網(wǎng)租房助手,m.kuairent.com,每天新增 500+房源