前面寫了一篇博文“學習js先把記憶體管理想清楚”後,可能是我表達的不夠清楚還是大家沒明白我的思想,抑或是有的人只為學語言而學語言(書本提什麼概念就照本宣科的去理解,沒有自己的思想,這是我所反對的),得到大家的反饋不是很好,當然這其中也有我個人的因數,沒表達清楚我的意思,但其中我確實看到一些同門的那種學習東西的硬思維,缺乏自己的思想封裝感到不屑,所以我先從自己改正,刪了那篇文章,此篇主要是為了延展那篇文章內容(講的更加詳細點)然後針對大家提出的質疑總結出大家的一些心理糾結原因,更願想大家學習東西不要那麼硬思維,要有自己的想法封裝,大家一起才能夠討論學習,不然大家一起都一個思維,都是從標準書本上的,那就沒有任何價值和意義。
我還是強調那句話,任何程式語言的目的都是為了操作記憶體資料(如何在記憶體中開闢空間放資料,如何把資料從記憶體中取出來並操作,如何把操作完的資料再放記憶體中)而發明出來的,因為定義的規則(就是各種語言各種規範)不一樣而已。js是門弱類型的語言,理解這個弱類型我們先從變數的定義說起(我個人喜歡從很簡單的例子去解釋),比如:var a=**;針對這個簡單代碼,解譯器是分兩階段來啟動並執行(js聲明,包括變數還有函數的聲明是在任何錶達式之前的),第一階段為聲明階段 var a ;(我個人喜歡把它理解為變數記憶體空間開闢階段),第二階段為賦值階段 a=**;第一階段時,CPU就在記憶體的棧中開闢了一個空間給這個變數a,然後這個變數的資料到底放什麼,怎麼放就取決於那個**了。js資料類型分參考型別(object array date regexp function)和實值型別(undefined null boolean number string,當然你也可以叫它基本類型),不用我說了吧,為什麼不拿具體的string、bool等來說因為沒整體性,決定變數的資料在記憶體中的儲存形式的因數就是這兩大類型決定的,依舊:
圖示文本解釋:
基本類型儲存在記憶體中的棧中,大小固定,複製其變數時會建立這個值的一個副本,用typeof確定一個值是哪種基本類型;
參考型別的變數實際上是一個指標,它儲存在棧中,指向堆記憶體中的對象複製參考型別變數實際是複製該指標,所以他們都指向同一個對象,
用instanceof確定一個值是哪種參考型別;
明白了參考型別和實值型別後我們來說說“學習js先把記憶體管理想清楚”博文裡博友的幾個質疑,還是那個demo:
Number.prototype.name="lyg";var a=23;alert(a.name);//彈出lyga.age=12;alert(a.age);//彈出undefine
還是來解釋那個問題,為什麼a.name這時表現的是對象形式,而且也運行正確,那麼大家就有理由認為是js弱類型作祟,變成了對象,那麼就更有理由去通過對象的形式去給它賦值並彈出它,可問題就是彈出undefine,上次的博友有很多人說這是原型繼承啊基礎封裝類型啊什麼的,那我告訴你們書本給你這個定義你就認定是這個原因,那你是否深度理解了我要說的話呢,這裡確實是屬於封裝類型(但這隻是js給我們的定義的一個概念而已,就好比別人給你它畫的一幅抽象畫,然後告訴你這叫春曉,然後有人問你為什麼叫春曉,你回答因為畫家就叫它春曉一樣),封裝類型是js定義出來的一個概念而已,任何資料都要反應到記憶體中去的,記憶體是沒有基本封裝類型的儲存形式的。實際上代碼運行到第三行時後台已經自動完成了一系列處理,後台會完成下列三步處理(這個過程是瞬時的,就是生命週期就是這行代碼的執行前後):
1,建立一個Number類型的執行個體
2,在執行個體上調用指定屬性name
3,銷毀這個執行個體
實際上就相當於執行了下列過程:
var a=new Number();
alert(a.name);
a=null;
所以後面再去像對象一樣給這個變數定義age屬性時,是不行的,因為它的類型已經是實值型別的資料23了