javaScript 中原型與原型鏈是什么?這個問題可能是我們?nèi)粘W習或工作經(jīng)常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!
公司主營業(yè)務:網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計、移動網(wǎng)站開發(fā)等業(yè)務。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)公司推出福貢免費做網(wǎng)站回饋大家。
javascript欄目簡單明了介紹原型與原型鏈。
在 JavaScript 中,原型和原型鏈是不可避免的重要概念,那么怎么去理解原型和原型鏈呢?下面是我對原型和原型鏈的理解和總結(jié)。也許有些理解還比較淺薄,隨著時間的推移和理解的深入,以后還會補充。如果大家發(fā)現(xiàn)我理解的有問題,歡迎大家在評論中指正。
在以往的學習過程中,我們曾通過學習面向?qū)ο笳Z言 java 了解到其有三個要素:封裝、繼承、多態(tài)。關(guān)于繼承,java 與 javascript 其實兩者并不完全一樣。
那么 javascript 到底是如何設(shè)計出來的呢?早期,瀏覽器只能瀏覽網(wǎng)頁內(nèi)容,而不能進行用戶交互,也就說當我們輸入賬號密碼進行登錄時,瀏覽器不能對其輸入內(nèi)容進行判斷,需要通過服務器進行判斷,而網(wǎng)景公司為了解決這一問題,發(fā)明一種與 java 搭配使用的輔助腳本語言,并在語法上有些類似。由此可以看出,javascript 受到 java 的影響,其都是對象類型,有對象則就會涉及到繼承機制,那么JS的繼承機制是怎么樣呢?
JS參考java的設(shè)計,使用new操作符生成對象,但其與java不同的是new后面跟的是 Construtor 而不是 Class 。
// java 中生成一個對象 Person p = new Person() // Person 指的是類名 // js 生成一個對象 function Person (age) { this.age = age this.nation = 'China' } var father = new Person(42) // Person 指的是構(gòu)造函數(shù) var mingming = new Person(11)復制代碼
構(gòu)造函數(shù)也是普通函數(shù),其也有 prototype 屬性,與普通函數(shù)的區(qū)別是其要求首字母大寫。若構(gòu)造函數(shù)使用new操作符調(diào)用時,其需要執(zhí)行四個步驟:
1. 創(chuàng)建一個新的對象
2. 將 this 指向這個新的對象
3. 執(zhí)行構(gòu)造函數(shù),給新對象添加屬性和方法
4. 返回這個新對象
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana')復制代碼
任何一個函數(shù)都有一個 prototype 屬性,它指向 prototype 對象。那么原型其實就是一個對象,在原型上定義的屬性,通過繼承(new 操作符實現(xiàn)),實例化的對象也擁有了該屬性。
原型與構(gòu)造函數(shù)的關(guān)系:構(gòu)造函數(shù)內(nèi)有一個 prototype 屬性,通過該屬性可以訪問到原型。
以構(gòu)造函數(shù)中的代碼為例,F(xiàn)ood 就是構(gòu)造函數(shù),F(xiàn)ood.prototype 就是原型,food 就是參照 Food.prototype 生成的一個對象。
實例是指一個構(gòu)造函數(shù)在原型上創(chuàng)建可以"繼承"的屬性和方法,并通過new操作符創(chuàng)建的對象。
簡單來說,我們使用 new 操作符創(chuàng)建一個 food 實例,并且可以通過 instanceof 檢驗實例與構(gòu)造函數(shù)之間的關(guān)系。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 實例化 var res = food instanceof Food // 檢查 food 是否為 Food 實例 console.log(res) // true復制代碼
當我們在原型上定義一個屬性時,實例也會"繼承"這個屬性。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 實例化 var res = food instanceof Food // 檢查 food 是否為 Food 實例 console.log(res) // true // 原型定義屬性 Food.prototype.type = 'object named Food' var foodRes = food.type // 實例繼承的屬性 console.log(foodRes) // object named Food復制代碼
任何對象在創(chuàng)建時都會有一個 __proto__屬性,它指向產(chǎn)生當前對象的構(gòu)造函數(shù)的原型對象。由于該屬性并非標準規(guī)定的屬性,所以不要隨便去更改該屬性的值,以免破壞原型鏈。也就是說,實例可以通過 __proto__屬性訪問到原型。
對象中的 __proto__屬性在所有實現(xiàn)中是無法訪問到的,但是可以通過 isPrototypeOf() 方法來確定對象之間是否存在著這種關(guān)系。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 實例化 console.log(food.__proto__ === Food.prototype) // true console.log(Food.prototype.isPrototypeOf(food)) // true復制代碼
構(gòu)造函數(shù)可以通過 prototype 屬性訪問到原型,那么原型也是能夠通過某種途徑訪問到構(gòu)造函數(shù)的,其就是原型中的一個屬性 constructor ,該屬性并不是真正的構(gòu)造函數(shù),真正的構(gòu)造函數(shù)是指 Constructor,兩者不要混淆了。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') console.log(Food.prototype.constructor === Food) //true復制代碼
關(guān)鍵:prototype 的 constructor 指向構(gòu)造函數(shù)本身
那么構(gòu)造函數(shù)、原型、實例三者的關(guān)系應該是這樣的:
為了更好地理解這一過程,我通過一個故事給大家梳理一下:
1. 很久以前,有個雕刻家偶然看到一個很精致的花瓶(原型 Food.prototype)
2. 一天,他想通過大批生產(chǎn)復刻這個花瓶來發(fā)家致富,于是他先分析這個花瓶,還原了雕刻的過程,并設(shè)計出了一條生產(chǎn)線(構(gòu)造器 Food)
3. 然后通過這條生產(chǎn)線,雕刻出許許多多的復刻花瓶。(實例 food)
proto 是任何對象都有的屬性,在js中會形成一條 proto 連接起來的鏈條,遞歸訪問 proto 直到值為 null ,這個搜索過程形成的鏈狀關(guān)系就是原型鏈。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 實例化 // 原型鏈 console.log(food.__proto__) // Food {} console.log(food.__proto__.__proto__) // {} console.log(food.__proto__.__proto__.__proto__) // null復制代碼
如下圖:
1. 每創(chuàng)建一個函數(shù)都會有一個 prototype 屬性,該屬性是一個指針,指向一個對象,該對象為原型對象(Food.prototype)。
2. 原型對象上的默認屬性 constructor 也是一個指針,指向其相關(guān)的構(gòu)造函數(shù)。
3. 通過 new 操作符產(chǎn)生的實例對象都會有一個內(nèi)部屬性指向原型對象,該實例對象可以訪問原型對象上的所有屬性和方法。
4. 實例可以通過內(nèi)部指針訪問到原型對象,原型對象也可以通過 constructor 找到構(gòu)造函數(shù)。
5. 每個構(gòu)造函數(shù)都有一個原型對象,原型對象上包含一個指向構(gòu)造函數(shù)的指針,實例包含一個指向原型對象的內(nèi)部指針。
6. __proto___的指向取決于對象創(chuàng)建時的實現(xiàn)方式。
7. 構(gòu)造函數(shù)實例,封裝的函數(shù),如果通過 new 操作符來調(diào)用則是構(gòu)造函數(shù),否則則不是。 8. 在整個原型鏈上尋找某個屬性,對性能有影響,越是上層的原型對象,對性能的影響越大。
9. js中一切皆對象,通過 new Function 的是函數(shù)對象,其構(gòu)造函數(shù)是 Function,而普通對象的構(gòu)造函數(shù)則是 Object 。
10. 每一個對象都有 __proto__屬性,而每一個函數(shù)對象才有 prototype 屬性。
感謝各位的閱讀!看完上述內(nèi)容,你們對javaScript 中原型與原型鏈是什么大概了解了嗎?希望文章內(nèi)容對大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當前名稱:javaScript中原型與原型鏈是什么
文章分享:http://jinyejixie.com/article24/gpedje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、虛擬主機、標簽優(yōu)化、關(guān)鍵詞優(yōu)化、網(wǎng)站設(shè)計公司、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)