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