摘要:值得注意的是原型對(duì)象也擁有一個(gè)屬性指向其函數(shù)。以上的原因就造成了很少有使用純的原型模式創(chuàng)建對(duì)象,而其他混合使用原型模式的創(chuàng)建對(duì)象模式就不在這里展開說(shuō)了。
第一次記錄自己學(xué)習(xí)的腳步,我選擇了JavaScript中自認(rèn)為比較熟悉的一小部分來(lái)說(shuō),誠(chéng)摯的希望能夠得到各位前輩的批評(píng)與指正。而對(duì)于看到我這篇筆記希望從這篇筆記中收獲知識(shí)的讀者,我希望你們可以參考權(quán)威,擁有自己的真知灼見而不聽我一家之言,以免有不正確的地方誤導(dǎo)了讀者。
1.原型,原型對(duì)象是什么?**1.原型(prototype)是函數(shù)的一個(gè)屬性,這個(gè)屬性是個(gè)指針指向原型對(duì)象。
2.原型對(duì)象(prototype object)是一個(gè)屬于其所在函數(shù)的空對(duì)象,可以通過它給函數(shù)添加屬性和方法。**
值得注意的是原型對(duì)象也擁有一個(gè)屬性——constructor指向其函數(shù)。
通過一張圖我們可以更好的理解這幾者的關(guān)系:
上圖給我們傳達(dá)了幾個(gè)信息:
**1.實(shí)例擁有一個(gè)屬性[[prototype]],這個(gè)屬性指向其構(gòu)造函數(shù)的原型對(duì)象。
2.原型對(duì)象也是構(gòu)造函數(shù)的實(shí)例**
我們知道,JavaScript是一個(gè)基于對(duì)象的語(yǔ)言,而與Java等語(yǔ)言不同的是JavaScript沒有類的概念。而要實(shí)現(xiàn)類的功能我們則需要模擬類。在模擬類的實(shí)現(xiàn)中使用原型和原型對(duì)象我們就可以更好的創(chuàng)建具有封裝性,共享性的類(對(duì)象),而這種創(chuàng)建類(對(duì)象)的模式就叫原型模式。
這也解釋了為什么在《JavaScript高級(jí)程序設(shè)計(jì)》中描述原型以及原型對(duì)象用于創(chuàng)建對(duì)象,而在《JavaScript權(quán)威指南》中描述原型以及原型對(duì)象用于創(chuàng)建類。(因?yàn)樵贘avaScript中沒有類,有類也只是對(duì)象模擬出來(lái)的,包括ES6中的class關(guān)鍵字)
3.該如何使用它?原型模式模擬類十分簡(jiǎn)單:
var Foo = function(){} Foo.prototype.username = "ec" console.log(Foo.prototype) // --> a{username = "ec"} var f = new Foo() console.log(f.username) //--> "ec" console.log(Foo.username) //--> underfined
我們可以發(fā)現(xiàn)兩個(gè)信息:
**1.原型對(duì)象與它所在函數(shù)同名
2.屬性已經(jīng)被添加進(jìn)了原型對(duì)象中
3.使用時(shí)必須實(shí)例化構(gòu)造器函數(shù)。**
需要注意的是原型模式模擬類是有缺點(diǎn)的,例如以下代碼:
function Person(){} Person.prototype = { constructor: Person, name: "李小山", age: 20, family: [ "李大山", "張曉梅", ], } var person1 = new Person() var person2 = new Person() person1.family.push("李巨山") console.log(person1.family) //--> ["李大山", "張曉梅", "李巨山"] console.log(person2.family) //--> ["李大山", "張曉梅", "李巨山"]
從上面這個(gè)例子我們可以得到幾個(gè)信息:
**1.因?yàn)樵湍J揭?guī)定我們?cè)谠蛯?duì)象上添加屬性與方法,所以無(wú)法傳遞初始化參數(shù)
2.因?yàn)檫^度的“共享”以至于當(dāng)一個(gè)實(shí)例改變了引用類型的值,所有實(shí)例的該值都會(huì)被改變。**
以上的原因就造成了很少有使用純的原型模式創(chuàng)建對(duì)象,而其他混合使用原型模式的創(chuàng)建對(duì)象模式就不在這里展開說(shuō)了。
4.還是不太明白原型對(duì)象、對(duì)象、函數(shù)終于講到了這部分,這個(gè)部分我們可以提一個(gè)更加具體的問題:
原型對(duì)象與對(duì)象、函數(shù)、構(gòu)造函數(shù)、實(shí)例的關(guān)系是什么?
首先是函數(shù)與構(gòu)造函數(shù)的區(qū)別:
構(gòu)造函數(shù)需要new操作符實(shí)例化才能使用
構(gòu)造函數(shù)沒有return語(yǔ)句
構(gòu)造函數(shù)this指向調(diào)用者往往是調(diào)用構(gòu)造函數(shù)的實(shí)例本身,而函數(shù)使用this則會(huì)指向window全局對(duì)象
構(gòu)造函數(shù)名首字母大寫(非強(qiáng)制性的)
而實(shí)例就是構(gòu)造函數(shù)創(chuàng)建出來(lái)的對(duì)象,擁有構(gòu)造函數(shù)的屬性與方法。
知道了這些后我們就可以通過這張圖來(lái)明確它們之間的關(guān)系了:
這個(gè)圖看似唬人,其實(shí)只需要知道三點(diǎn)就可以秒懂了:
1.JavaScript中一切皆是對(duì)象
2.所有對(duì)象有[[prototype]]屬性,指向其構(gòu)造函數(shù)的原型對(duì)象
3.所有函數(shù)都有prototype屬性,指向其原型對(duì)象
4.所有實(shí)例都有constructor屬性,指向其構(gòu)造函數(shù)
圖中有兩個(gè)地方可能比較難以理解:
為什么內(nèi)置對(duì)象Function()的原型對(duì)象function()是個(gè)函數(shù)對(duì)象?
因?yàn)閮?nèi)置對(duì)象Function()也是函數(shù),而函數(shù)就是function,這就造成了一種雞生蛋、蛋生雞的問題,而讓Function()的原型對(duì)象為函數(shù)對(duì)象就可以添加函數(shù)方法給Function(),這也解釋了為什么Function()的[[prototype]]屬性也指向其原型對(duì)象。
內(nèi)置對(duì)象的原型對(duì)象的[[prototype]]屬性指向誰(shuí)?
這也是一個(gè)雞生蛋、蛋生雞的問題,是對(duì)象創(chuàng)建了對(duì)象,那么追根溯源誰(shuí)真正創(chuàng)建了對(duì)象呢?答案就是Null空。(圖中這個(gè)地方箭頭指向錯(cuò)誤,望見諒)
至此,我們算是大致了解了JavaScript中有關(guān)于原型的基本知識(shí)了,其實(shí)還有很多問題我們沒有解決,比如比原型模式更好的創(chuàng)建對(duì)象模式,還有關(guān)系圖中有關(guān)于繼承的部分都還沒用詳細(xì)說(shuō)明。篇幅有限,下次再聊。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107626.html
摘要:首先,需要來(lái)理清一些基礎(chǔ)的計(jì)算機(jī)編程概念編程哲學(xué)與設(shè)計(jì)模式計(jì)算機(jī)編程理念源自于對(duì)現(xiàn)實(shí)抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機(jī)制一直以來(lái)都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因?yàn)榻^大多數(shù)人沒有想要深刻理解這個(gè)機(jī)制的內(nèi)涵,以及越來(lái)越多的開發(fā)者缺乏計(jì)算機(jī)編程相關(guān)的基礎(chǔ)知識(shí)。對(duì)于這樣的開發(fā)者來(lái)說(shuō) J...
摘要:每一個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都會(huì)默認(rèn)的連接到該神秘對(duì)象上。在構(gòu)造方法中也具有類似的功能,因此也稱其為類實(shí)例與對(duì)象實(shí)例一般是指某一個(gè)構(gòu)造函數(shù)創(chuàng)建出來(lái)的對(duì)象,我們稱為構(gòu)造函數(shù)的實(shí)例實(shí)例就是對(duì)象。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來(lái)的。 本文您將看到以下內(nèi)容: 傳統(tǒng)構(gòu)造函數(shù)的問題 一些相關(guān)概念 認(rèn)識(shí)原型 構(gòu)造、原型、實(shí)例三角結(jié)構(gòu)圖 對(duì)象的原型鏈 函數(shù)的構(gòu)造函數(shù)Function 一句話說(shuō)明什么...
摘要:前言作為前端高頻面試題之一,相信很多小伙伴都有遇到過這個(gè)問題。 前言 作為前端高頻面試題之一,相信很多小伙伴都有遇到過這個(gè)問題。那么你是否清楚完整的了解它呢? 國(guó)際慣例,讓我們先拋出問題: 什么是原型、原型鏈 它們有什么特點(diǎn) 它們能做什么 怎么確定它們的關(guān)系 或許你已經(jīng)有答案,或許你開始有點(diǎn)疑惑,無(wú)論是 get 新技能或是簡(jiǎn)單的溫習(xí)一次,讓我們一起去探究一番吧 如果文章中有出現(xiàn)紕...
摘要:深入系列的第一篇,從原型與原型鏈開始講起,如果你想知道構(gòu)造函數(shù)的實(shí)例的原型,原型的原型,原型的原型的原型是什么,就來(lái)看看這篇文章吧。讓我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系在這張圖中我們用表示實(shí)例原型。 JavaScript深入系列的第一篇,從原型與原型鏈開始講起,如果你想知道構(gòu)造函數(shù)的實(shí)例的原型,原型的原型,原型的原型的原型是什么,就來(lái)看看這篇文章吧。 構(gòu)造函數(shù)創(chuàng)建對(duì)象 我們先...
摘要:深入理解原型與繼承看過不少書籍,不少文章,對(duì)于原型與繼承的說(shuō)明基本上讓人不明覺厲,特別是對(duì)于習(xí)慣了面向?qū)ο缶幊痰娜藖?lái)說(shuō)更難理解,這里我就給大家說(shuō)說(shuō)我的理解。 深入理解:JavaScript原型與繼承 看過不少書籍,不少文章,對(duì)于原型與繼承的說(shuō)明基本上讓人不明覺厲,特別是對(duì)于習(xí)慣了面向?qū)ο缶幊痰娜藖?lái)說(shuō)更難理解,這里我就給大家說(shuō)說(shuō)我的理解。 首先JavaScript是一門基于原型編程的語(yǔ)言...
閱讀 2079·2021-11-24 09:39
閱讀 802·2021-09-30 09:48
閱讀 989·2021-09-22 15:29
閱讀 2429·2019-08-30 14:17
閱讀 1898·2019-08-30 13:50
閱讀 1356·2019-08-30 13:47
閱讀 990·2019-08-30 13:19
閱讀 3430·2019-08-29 16:43