摘要:面向?qū)ο笾玩湆ο蠛蛯ο笾g的關(guān)系注意這個系列文章要經(jīng)常站在之父的視角去思考。思考問題我們都知道都屬于那么既然他們都是對象一定有某些相同之處吧對象和對象之間有什么關(guān)聯(lián)呢如果說你沒有思考過這個問題那么可以換一個更具體的問題。
JS面向?qū)ο笾?【原型鏈】(對象和對象之間的關(guān)系)
注意這個系列文章,要經(jīng)常站在JS之父的視角去思考。
牢記我們的需求,我要在JS沒有class的情況下,那么利用JS現(xiàn)有的東西,搞出類似class的東西。
回一下JS有什么? 有7種數(shù)據(jù)類型:
6個基本數(shù)據(jù)類型 : string number boolean null undefined symbol
1個引用類型 : obj (你需要知道前6個基本數(shù)據(jù)類型是存儲在棧中的, 1個引用類型obj存儲是的引用,它的值存儲在堆中的.)
對象分成3類: 普通對象 、數(shù)組對象 、函數(shù)對象。
思考問題1: 我們都知道array function都屬于object,那么既然他們都是對象,一定有某些相同之處吧,對象和對象之間有什么關(guān)聯(lián)呢?
如果說你沒有思考過這個問題,那么可以換一個更具體的問題。
思考問題2: 打印這段代碼,到瀏覽器控制臺,你會發(fā)現(xiàn)我們空對象,"自帶"了一個toString()?
var obj = { name: "ziwei", sex : "男", eat : function(){} } obj.toString()
問題1: array funciton obj 都是對象,那么為什么說他們都是對象,通過什么關(guān)聯(lián)起來的?
問題2: 為什么一個空對象,"自帶"toString()方法?
如果你不清楚以上問題的答案,恭喜你,這篇文章的主題【原型鏈】就可以清楚的解答你的疑惑。
原型鏈 什么場景下,需要原型鏈。還是上面這段代碼
var obj = { name: "ziwei", sex : "男", eat : function(){} } obj.toString()
如果我們想自己實現(xiàn),讓obj,具有toString()怎么辦? 直覺肯定是添加在obj上咯。
這樣因為toString(),是函數(shù)對象,所以需要在內(nèi)存中開辟一塊空間,存放toString()
現(xiàn)在,我們要聲明100個obj對象,他們都需要具備toString()怎么辦?
如果循環(huán)100次給每個obj都添加toString(),需要在內(nèi)存空間開辟100個空間,存在100個相同的toString(),勢必造成內(nèi)存空間的浪費(fèi),在JS被創(chuàng)造時,內(nèi)存還是十分寶貴的資源。
所以JS之父想出一個辦法。把對象需要共享的屬性和方法,放到一個內(nèi)存空間里,然后每一個對象都有一個屬性都指向這一個空間。
所以原型鏈被發(fā)明,最樸素的想法就是節(jié)省內(nèi)存空間。
JS里如何設(shè)計原型鏈規(guī)則的呢?1.所有對象都有的這個屬性長得很奇怪,叫做 proto
var obj = {} console.log(obj.__proto__ ) 訪問,你就可以查看所有object都共享的屬性。
2.這個__proto__所指向的那塊內(nèi)存空間里的屬性,并不是在var obj = {}時,才被添加進(jìn)去的,而是一直都存在的。
通過 window.Object.prototype 你同樣可以訪問到這個共享的內(nèi)存空間
3.__proto__里面還可以有__proto__,畢竟被稱為原型鏈嘛。
之所以需要"鏈",你可以看這樣一個例子
var arr = [] 數(shù)組作為一個數(shù)組是有push()方法的, 可是我們查看 window.Object.prototype里并沒有共享push方法
我們?yōu)榱藢崿F(xiàn)數(shù)組有push方法,但是不能讓所有的對象都有push方法,為了實現(xiàn)這個需求,JS是這樣設(shè)計的。
JS另外開辟了一個內(nèi)存空間,用來專門存儲數(shù)組的共有方法和屬性。你可以用過window.Array.prototype來訪問它
這樣JS數(shù)組,arr通過__proto__繼承了Array.prototype的方法,有通過Array.prototype.__proto__繼承了Object.prototype上的訪問。
類似的我們訪問obj.name時,JS會在obj內(nèi)部尋找name屬性,如果沒有,就會到__proto__中去尋找name,一直到Object.prototype如果還是沒有name,就會返回undefined
所以這種依靠原型來繼承的方式,很想一個鏈條,一層一層的向上尋找,所以叫做原型鏈,原型鏈的頂端就是Object.prototype
最后回答文章最初的2個問題:問題1: array funciton obj 都是對象,那么為什么說他們都是對象,通過什么關(guān)聯(lián)起來的?
他們就是通過__proto__關(guān)聯(lián)的。
Array.prototype.__proto__ 繼承了 Object.prototype
Function.prototype.__proto__ 繼承了 Object.prototype
他們同根同源,都繼承自O(shè)bject.prototype,數(shù)組只是比普通的對象多了一些方法,所以他們都是對象唄
![圖片上傳中...]
問題2: 為什么一個空對象,"自帶"toString()方法?
因為所有對象都自帶__proto__屬性,這個屬性指向Object.prototype這個內(nèi)存空間。
因為Object.prototype存儲著有toString(),所以所有對象都有。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/92415.html
摘要:避免脆弱的基類問題。紅牌警告沒有提到上述任何問題。單向數(shù)據(jù)流意味著模型是單一的事實來源。單向數(shù)據(jù)流是確定性的,而雙向綁定可能導(dǎo)致更難以遵循和理解的副作用。原文地址 1. 你能說出兩種對 JavaScript 應(yīng)用開發(fā)者而言的編程范式嗎? 希望聽到: 2. 什么是函數(shù)編程? 希望聽到: 3. 類繼承和原型繼承的不同? 希望聽到 4. 函數(shù)式編程和面向?qū)ο缶幊痰膬?yōu)缺點? ...
摘要:指向原型對象的構(gòu)造函數(shù)二原型鏈?zhǔn)裁词窃玩溤玩溇褪菍嵗龑ο蠛驮蛯ο笾g的關(guān)系,他們使用來關(guān)聯(lián)。改變指向?qū)崿F(xiàn)繼承創(chuàng)建類創(chuàng)建原型對象每天堅持鍛煉創(chuàng)建構(gòu)造函數(shù)函數(shù)就是改變執(zhí)行代碼片段中指向。 一. JS原型的簡單理解 1.1 prototype prototype:是一個函數(shù)的屬性,每個函數(shù)中都會有一個prototype屬性,這個屬性是一個指針,指向一個對象。在JavaScript...
摘要:指向原型對象的構(gòu)造函數(shù)二原型鏈?zhǔn)裁词窃玩溤玩溇褪菍嵗龑ο蠛驮蛯ο笾g的關(guān)系,他們使用來關(guān)聯(lián)。改變指向?qū)崿F(xiàn)繼承創(chuàng)建類創(chuàng)建原型對象每天堅持鍛煉創(chuàng)建構(gòu)造函數(shù)函數(shù)就是改變執(zhí)行代碼片段中指向。 一. JS原型的簡單理解 1.1 prototype prototype:是一個函數(shù)的屬性,每個函數(shù)中都會有一個prototype屬性,這個屬性是一個指針,指向一個對象。在JavaScript...
摘要:指向原型對象的構(gòu)造函數(shù)二原型鏈?zhǔn)裁词窃玩溤玩溇褪菍嵗龑ο蠛驮蛯ο笾g的關(guān)系,他們使用來關(guān)聯(lián)。改變指向?qū)崿F(xiàn)繼承創(chuàng)建類創(chuàng)建原型對象每天堅持鍛煉創(chuàng)建構(gòu)造函數(shù)函數(shù)就是改變執(zhí)行代碼片段中指向。 一. JS原型的簡單理解 1.1 prototype prototype:是一個函數(shù)的屬性,每個函數(shù)中都會有一個prototype屬性,這個屬性是一個指針,指向一個對象。在JavaScript...
閱讀 1878·2023-04-26 02:46
閱讀 2011·2021-11-25 09:43
閱讀 1152·2021-09-29 09:35
閱讀 2107·2019-08-30 15:56
閱讀 3431·2019-08-30 15:54
閱讀 2640·2019-08-29 16:35
閱讀 3129·2019-08-29 15:25
閱讀 3300·2019-08-29 14:01