摘要:但這兩個對象的原型指向了同一個實例對象,這個實例對象同樣是存在棧內存中的然后指向了一個對象。實際是在的實例對象增加一個屬性,并將屬性賦值為,但它并沒有修改原型鏈上的屬性。側重理解的指向問題
直接先貼題目吧
function A() { this.name = "a" this.color = ["green", "yellow"] } function B() { } B.prototype = new A() var b1 = new B() var b2 = new B() b1.name = "change" b1.color.push("black")
console.log("b1", b1)
console.log("b2", b2)
console.log(b1.name) // change
console.log(b2.name) // a
console.log(b1.color) // ["green", "yellow", "black"]
console.log(b2.color) // ["green", "yellow", "black"]
這其實就是我們的常見繼承模式之一,原型繼承,為何會出現這樣的情況呢?
最大的疑惑是,為何兩個實例對象b1,b2里面的color屬性都被修改了?
又為何b1.name = change 而b2.name 卻沒有發生改變。
首先,你得有原型鏈繼承的知識點,有了這個知識點后,我們再理解下我們經常掛在嘴邊的基本數據類型和
引用數據類型,他們的存儲方式和讀取方式有何異同,帶著這一些疑惑,我們再看下棧內存和堆的概念
看了上圖,一目了然的看到,不管是基本數據類型還是引用類型,實際都是存在棧內存的,只不過引用數據類型還會指向一個具體的堆。他們的區別我簡單就闡述這么一些。
再剖析上面的代碼是如何執行或者指向的。
首先:b1和b2實例化是存在棧內存里面,然后指向了堆內存的兩個對象。但這兩個對象的原型指向了同一個實例對象,這個實例對象同樣是存在棧內存中的(然后指向了一個對象)。所以簡而言之,b1和b2的原型對象指向了同一個實例對象(A的實例對象)。
b1.name = "change"
實際是在b1的實例對象增加一個屬性name,并將name屬性賦值為change,但它并沒有修改原型鏈上的name屬性。
b1.color.push("black")
這里涉及到原型鏈向上查找屬性的知識點,實例對象b1里面并沒有color屬性,于是去原型鏈上尋找,結果在A的實例對象找到了color,但此時的color屬性指向的是一個引用類型,而b1和b2都繼承于A這個實例對象,根據引用類型color指向一個堆數組來看,當b1修改了原型上的color屬性,實際也就修改了b2上面的color屬性。再強調下,因為color屬性是原型對象上的一個引用類型屬性,指向了同一個數組對象
那么如何規避color屬性被指向同一個引用類型的問題呢?
實際我們上面就是運用到繼承里面的一個原型鏈繼承的方法。
還有一種繼承是構造函數繼承
稍微修改下:
function B() { A.call(this) }
經過改動后,我們每次在實例化B的時候,會將實例化對象的引用對象作為參數傳遞到B這個構造函數,在間接調用A函數的時候,也修改了A執行的時候this的執行問題。此時this的執行不再是window而是實例化的對象b1或b2.
分析下,我們不寫A.call(this)這句代碼的時候,A的實例對象實際就是指向A實例對象的本身,這句話理解起來有點傲,執行了A.call(this)后,這里翻譯過來我想應該是這樣的,不知道是否有錯?
調用A,而不是實例化A,即A(),但此時A的this并不是window對象,這里沒有實例A所以,this不是A實例化指向的那個引用對象。然后我們認為的修改了A這個函數執行時執行上下文的this執行,這個this此時成了b1或者b2實例對象。
此時我們再修改b1.color的時候,同樣會去原型上去找color熟悉,但此時原型鏈上的this已經指向了b1這個實例化對象,所以當我們修改b1.color的時候,實際只修改了b1這個實例化對象對應原型上的那個對象。而b2.color并不會被改變。側重理解this的指向問題
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93865.html
摘要:探討判斷橫豎屏的最佳實現前端掘金在移動端,判斷橫豎屏的場景并不少見,比如根據橫豎屏以不同的樣式來適配,抑或是提醒用戶切換為豎屏以保持良好的用戶體驗。 探討判斷橫豎屏的最佳實現 - 前端 - 掘金在移動端,判斷橫豎屏的場景并不少見,比如根據橫豎屏以不同的樣式來適配,抑或是提醒用戶切換為豎屏以保持良好的用戶體驗。 判斷橫豎屏的實現方法多種多樣,本文就此來探討下目前有哪些實現方法以及其中的優...
摘要:引言滿滿的干貨,面試必系列,參考大量資料,并集合自己的理解以及相關的面試題,對核心知識點中的作用域閉包上下文進行了梳理。本篇重點介紹閉包和。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 滿滿的干貨,面試必bei系列,參考大量資料,并集...
摘要:函數式編程前端掘金引言面向對象編程一直以來都是中的主導范式。函數式編程是一種強調減少對程序外部狀態產生改變的方式。 JavaScript 函數式編程 - 前端 - 掘金引言 面向對象編程一直以來都是JavaScript中的主導范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數式編程越來越多得受到開發者的青睞。函數式編程是一種強調減少對程序外部狀態產生改變的方式。因此,...
摘要:下面我們來使用面向對象類圖這里就不再畫了首先面試題中所提到的我們都可以看成類,比如停車場是一個類吧,它里面的車位是一個類吧,攝像頭,屏幕。。。 以下是某場的一道面試題(大概): 1、一個停車場,車輛入場時,攝像頭記錄下車輛信息2、屏幕上顯示所接收的車輛的信息情況(車牌號)以及各層車位的車位余量3、停車場一共四層車位,其中的三層都為普通車位,還有一層為特殊車位(體現在停車計費價格上面的不...
閱讀 1759·2021-11-25 09:43
閱讀 1953·2019-08-30 13:56
閱讀 1214·2019-08-30 12:58
閱讀 3412·2019-08-29 13:52
閱讀 755·2019-08-26 12:17
閱讀 1452·2019-08-26 11:32
閱讀 934·2019-08-23 13:50
閱讀 1298·2019-08-23 11:53