原始值:
首先,先來說一下棧,棧的特點為先入後出。採用動態一維陣列來儲存棧。所謂動態,指的是棧的大小可以根據需要增加。
原始值位於棧內,也遵循先入後出的特點。重點是:賦值為copy的關係。
例如:
請大家看到這裡停下來想一想,輸出的a,b的值分別是什麼?b是否會隨著a的改變而改變?
試驗後,想必都可以得到20 10的結果,即b的值並沒有隨著a的改變而改變。這是為什麼?
棧記憶體之間的賦值為copy的關係,b = a的過程相當於三步:取出a,copy10,把10再賦給b,這樣b的值是a的值的副本。此刻無論再怎麼改變a的值對b都並不受影響。
引用值位於堆內,類似於下圖這樣的過程,先入先出:
例如:定義乙個引用值時會發生這樣乙個過程:例如var arr = [1,2,3,4];,此時申請乙個叫做arr的房間,重點來了:它的位址是存在棧記憶體,即它在棧內申請了乙個名為arr的房間,假設位址為heap1;那麼後面的[1,2,3,4]放在**呢?[1,2,3,4]放在堆記憶體中。總結來說:引用值的位址位於棧記憶體中,引用值的值位於堆記憶體中。這樣說的話,前面所說的引用值位於堆記憶體,也就有些不確切了吧。讓我們來舉個例子:
var arr = [1,2,3];
var arr1 = arr;
arr1的值現在是多少呢?自然是[1,2,3],然而過程卻沒有我們想象的那麼簡單。var arr1時在佔記憶體中申請了乙個房間,將它的位址存入,假設為heap2,此時在棧記憶體中有兩個房間,乙個存入了heap1,另乙個存入了heap2,陣列arr的定義使heap1指向堆記憶體中的[1,2,3],由於語句arr1 = arr;的緣故,heap2也指向了[1,2,3],此時arr1的值便為[1,2,3]。那麼咱們現在來換一種方式吧:
var arr = [1,2,3];
var arr1 = arr;
arr.push(4);
此時,arr1的值是多少呢?考慮一下現在已有的情況heap1和heap2都指向堆記憶體中的同乙個房間,當房間裡多出了乙個數,arr1和arr自然也會跟著改變,所以arr1的的值現在是[1,2,3,4]。那麼咱們再接著來換一種方式吧:
var arr = [1,2,3];
var arr1 = arr;
arr = [1,3];
根據上面的規律,arr1的值按理說應該是[1,3]吧,但真的是這樣嗎?顯然不是。原因在於:arr = [1,3];這條語句相當於在堆記憶體中開闢出一間新的房間,arr在棧內的位址heap1改變指向,指到[1,3]的房間,然而此刻arr2的位址heap2依舊指向原來[1,2,3]的房間,所以此時,arr1並沒有隨著arr的改變而改變,arr1的值依舊為[1,2,3];
總結來說:1.原始值賦值後,乙個值改變並不影響另乙個值。
2.(1)引用值往裡push的時候,不會發生新房間的建立,乙個值的改變會影響另乙個值隨之改變。
(2)當引用值直接用賦值符號改變自己的值時(arr = [1,3]),相當於建立出新的房間,棧中的位址改變指向,乙個值的改變並不影響另乙個值的改變。
前端學習總結 2
第一 元素之間的關係 父元素 直接包含子元素的元素 子元素 直接包含子元素的元素 祖先元素 直接或間接包含後代元素的元素 後代元素 直接或間接被祖先元素包含的元素 兄弟元素 擁有相同父元素的元素叫做兄弟元素 第二 如何選擇後代元素 全部 一般用這個 相容性好 語法 祖先元素1空格祖先元素2 自定義 ...
階段總結2
1 遊戲開發中的可配置性 一 需求 與其他業務需求不同,或者更突出的是,遊戲邏輯開發需要有極強的可配置性。主要原因在於 1 遊戲後端工程師僅僅是實現了一套邏輯框架,框架中具體的數值是有策劃配置的 2 類似npc對話的具體內容由策劃配置 3 有一些行為由策劃配置 程式僅僅給出乙個解決方案,組合成什麼樣...
通訊階段總結(2)
以下是在通訊階段遇到的問題的部分總結,或者說是需要注意的地方。1 埠被占用 在測試程式時,有時會發現telnet 不上伺服器,這時應該首先懷疑是埠出了問題。一般來說埠數1024 以下的埠會被系統占用,系統開放的埠從0 65535 這時我們就應該選擇1024 之後的埠才不會出問題。2 死迴圈 我們在寫...