js變數、作用域及記憶體詳解_基礎知識
基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在記憶體中佔有固定的大小空間,他們的值保存在堆疊空間,我們透過按值來存取的。
(1)值類型:數值、布林值、null、undefined。
(2)引用類型:物件、陣列、函數。
如果賦值的是引用型別的值,則必須在堆記憶體中為這個值分配空間。由於這種值的大小不固定(物件有很多屬性和方法),因此不能把他們保存到堆疊記憶體中。但記憶體位址大小是固定的,因此可以將記憶體位址保存在堆疊記憶體中。
<script type="text/javascript”> var box = new Object(); //创建一个引用类型 var box = "lee"; //基本类型值是字符串 box.age = 23; //基本类型值添加属性很怪异,因为只有对象才可以添加属性。 alert(box.age); //不是引用类型,无法输出; </script>
簡而言之,堆記憶體存放引用值,堆疊記憶體存放固定型別值。
<script type="text/javascript"> var man = new Object();//man指向了栈内存的空间地址 man.name = "Jack"; var man2 = man;//man2获得了man的指向地址 alert(man2.name);//两个都弹出Jack alert(man.name); </script>
複製變數值
再看下面這個例子:
<script type="text/javascript"> var man = new Object();//man指向了栈内存的空间地址 man.name = "Jack"; var man2 = man;//man2获得了man的指向地址 man2.name = "ming";//因为他们都指向同一个object,同一个name,不管修改谁,大家都修改了 alert(man2.name);//两个都弹出ming alert(man.name); </script>
由以上可以得出:在變數複製方面,基本型別和參考型別也有所不同,基本型別複製的是值本身,而引用型別複製的是位址。
傳遞參數
ECMAScript中,所有函數的參數都是按值傳遞的,
<script type="text/javascript"> function box(num){ //按值传递 num+=10; return num; } var num = 10; var result = box(num); alert(result); //如果是按引用传递,那么函数里的num会成为类似全局变量,把外面的number替换掉 alert(num); //也就是说,最后应该输出20(这里输出10) </script>
javascript沒有按引用傳遞的,如果存在引用傳遞的話,那麼函數內的變數將是全域變量,在外部也可以存取。但這明顯是不可能的。
執行環境及作用域
執行環境是javascript中最重要的概念之一,執行環境定義了變數或函數有權存取其他資料。
全域執行環境是最外圍的執行環境,在web瀏覽器中,全域執行環境是window對象,因此,所有的全域變數的函數都是作為window的屬性和方法創建的。
<script type="text/javascript"> var name = "Jack"; //定义全局变量 function setName(){ return "trigkit4"; } alert(window.name); //全局变量,最外围,属于window属性 alert(window.setName()); //全局函数,最外围,属于window方法 </script>
當執行環境內的程式碼執行完畢後,該環境被銷毀,保存其中的變數和函數也隨之銷毀,如果是全域環境,需所有程式執行完畢或網頁完畢後才會銷毀。
去掉var的局部變數
<script type="text/javascript"> var name = "Jack"; function setName(){ name = "trigkit4"; //去掉var变成了全局变量 } setName(); alert(name);//弹出trigkit4 </script>
透過傳參,也是局部變數
<script type="text/javascript"> var name = "Jack"; function setName(name){ //通过传参,也是局部变量 alert(name); } setName("trigkit4");//弹出trigkit4 alert(name);//弹出Jack </script>
函數體內也包含函數,只有這個函數可以存取內一層的函數
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 return 21; } } alert(setYear());//无法访问,出错 </script>
可以透過以下方法存取:
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 return 21; } return setYear(); } alert(setName()); //弹出21 </script>
再作用域範例:
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 var b = "hi"; //变量b的作用域在setYear()内 return 21; } alert(b);//无法访问 } </script>
當程式碼在一個環境中執行的時候,就會形成一種叫做作用域鏈的東西,它的用途是保證對執行環境中有訪問權限的變數和函數進行有序存取(指按照規則層次來存取),作用域鏈的前端,就是執行環境的變數物件。
作用域
變數沒有在函數內宣告或宣告的時候沒有帶var就是全域變量,擁有全域作用域,window物件的所有屬性擁有全域作用域;在程式碼任何地方都可以訪問,函數內部宣告並且以var修飾的變數就是局部變量,只能在函數體內使用,函數的參數雖然沒有使用var但仍是局部變數。
沒有區塊級作用域
沒有區塊級作用域
// if语句: <script type="text/javascript"> if(true){ //if语句的花括号没有作用域的功能。 var box = "trigkit4"; } alert(box);//弹出 trigkit4 </script>
for迴圈語句也是如此。
變數的查詢
在變數的查詢中,存取局部變數比全域變數來得快,因此不需要向上搜尋作用域鏈。
如下例:
<script type="text/javascript"> var name = "Jack"; function setName(){ var name = "trigkit4"; return name; //从底层向上搜索变量 } alert(setName()); </script>
記憶體問題
javascript具有自動垃圾回收機制,一旦資料不再使用,可以將其設為"null"來釋放引用
循環引用
一個很簡單的例子:一個DOM物件被一個Javascript物件引用,同時引用同一個或其它的Javascript對象,這個DOM物件可能會引發記憶體外洩。這個DOM物件的引用將不會在腳本停止的時候被垃圾回收器回收。要破壞循環引用,引用DOM元素的物件或DOM物件的參考需要被賦值為null。
閉包
在閉包中引入閉包外部的變數時,當閉包結束時此物件無法被垃圾回收(GC)。
var a = function() { var largeStr = new Array(1000000).join('x'); return function() { return largeStr; } }();
DOM洩漏
當原有的COM被移除時,子結點引用沒有被移除則無法回收。
var select = document.querySelector; var treeRef = select('#tree'); //在COM树中leafRef是treeFre的一个子结点 var leafRef = select('#leaf'); var body = select('body'); body.removeChild(treeRef); //#tree不能被回收入,因为treeRef还在 //解决方法: treeRef = null; //tree还不能被回收,因为叶子结果leafRef还在 leafRef = null; //现在#tree可以被释放了。
Timers計(定)時器外洩
定時器也是常見產生記憶體外洩的地方:
for (var i = 0; i < 90000; i++) { var buggyObject = { callAgain: function() { var ref = this; var val = setTimeout(function() { ref.callAgain(); }, 90000); } } buggyObject.callAgain(); //虽然你想回收但是timer还在 buggyObject = null; }
偵錯記憶體
Chrome自帶的記憶體偵錯工具可以很方便地查看記憶體使用情況和記憶體外洩:
在 Timeline -> Memory 點選record即可:

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

對於機械硬碟、或SATA固態硬碟,軟體運轉速度的提升會有感覺,如果是NVME硬碟,可能感覺不到。一,註冊表導入桌面新建一個文字文檔,複製貼上如下內容,另存為1.reg,然後右鍵合併,並重新啟動電腦。 WindowsRegistryEditorVersion5.00[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\MemoryManagement]"DisablePagingExecutive"=d

typedef struct 在 C 語言中用於建立結構體類型別名,簡化結構體使用。它透過指定結構體別名將一個新的資料類型作為現有結構體的別名。優點包括增強可讀性、程式碼重複使用和類型檢查。注意:在使用別名前必須定義結構體,別名在程式中必須唯一且僅在其宣告的作用域內有效。

本站9月3日消息,韓媒etnews當地時間昨報道稱,三星電子和SK海力士的「類HBM式」堆疊結構行動記憶體產品將在2026年後實現商業化。消息人士表示這兩大韓國記憶體巨頭將堆疊式行動記憶體視為未來重要收入來源,並計劃將「類HBM記憶體」擴展到智慧型手機、平板電腦和筆記型電腦中,為端側AI提供動力。綜合本站先前報導,三星電子的此類產品叫做LPWideI/O內存,SK海力士則將這方面技術稱為VFO。兩家企業使用了大致相同的技術路線,即將扇出封裝和垂直通道結合在一起。三星電子的LPWideI/O內存位寬達512

JavaScript 閉包的優點包括維持變數作用域、實作模組化程式碼、延遲執行和事件處理;缺點包括記憶體洩漏、增加了複雜性、效能開銷和作用域鏈影響。

C++ 中的 #include 預處理器指令將外部來源檔案的內容插入到目前原始檔案中,以複製其內容到目前原始檔案的相應位置。主要用於包含頭文件,這些頭文件包含程式碼中所需的聲明,例如 #include <iostream> 是包含標準輸入/輸出函數。

本站6月7日消息,金邦(GEIL)在2024台北國際電腦展上推出了其最新DDR5解決方案,而且給出了SO-DIMM、CUDIMM、CSODIMM、CAMM2和LPCAMM2等版本可選。 ▲圖來源:Wccftech如圖所示,金邦展出的CAMM2/LPCAMM2記憶體採用非常緊湊的設計,最高可提供128GB的容量,速度最高可達8533MT/s,其中部分產品甚至可以在AMDAM5平台上穩定超頻至9000MT/s,且無需任何輔助散熱。據介紹,金邦2024款PolarisRGBDDR5系列記憶體最高可提供8400

C++智慧指標的生命週期:建立:分配記憶體時建立智慧指標。所有權轉移:透過移動操作轉移所有權。釋放:智慧指標離開作用域或被明確釋放時釋放記憶體。物件銷毀:所指向物件被銷毀時,智慧型指標成為無效指標。

本站7月23日消息,微電子標準制定方JEDEC固態技術協會當地時間22日宣布,DDR5MRDIMM和LPDDR6CAMM內存技術規範即將正式推出,並介紹了這兩項內存的關鍵細節。 DDR5MRDIMM中的「MR」即MultiplexedRank(多路復用列),這意味著此記憶體支援兩個或以上的Rank(列),並可在單一通道上組合和傳輸多個資料訊號,無需額外的物理連線就能有效提升頻寬。 JEDEC規劃了多代DDR5MRDIMM內存,目標最終將其頻寬提升至12.8Gbps,較DDR5RDIMM內存目前的6.4
