javascript學(xué)習(xí)筆記(一)——內(nèi)存管理

內(nèi)存生命周期

不管什么程序語言,內(nèi)存生命周期基本是一致的:

  1. 分配你所需要的內(nèi)存
  2. 使用分配到的內(nèi)存(讀、寫)
  3. 不需要時將其釋放\歸還

在 JavaScript 中,最后一步是隱藏的、透明的。

JavaScript 的內(nèi)存分配

  • JavaScript 在定義變量時就完成了內(nèi)存分配。
var a = 123; // 給數(shù)值變量分配內(nèi)存

var b = "azerty"; // 給字符串分配內(nèi)存
  • 通過函數(shù)調(diào)用的內(nèi)存分配
var c = new Date(); // 分配一個 Date 對象

var d = document.createElement('div'); // 分配一個 DOM 元素
  • 有些方法分配新變量或者新對象
var e = "azerty";

var f = e.substr(0, 3); // f 是一個新的字符串

// 因為字符串是不變量,JavaScript 可能決定不分配內(nèi)存,只是存儲了 [0-3] 的范圍。

值的使用

使用值的過程實際上是對分配內(nèi)存進(jìn)行讀取與寫入的操作。讀取與寫入可能是寫入一個變量或者一個對象的屬性值,甚至傳遞函數(shù)的參數(shù)。

當(dāng)內(nèi)存不再需要使用時釋放(垃圾回收)

引用計數(shù)

此算法把“對象是否不再需要”簡化定義為“對象有沒有其他對象引用到它”。如果沒有引用指向該對象(零引用),對象將被垃圾回收機(jī)制回收。

標(biāo)記清除

這個算法把“對象是否不再需要”簡化定義為“對象是否可以獲得”。

當(dāng)變量進(jìn)入環(huán)境時,我們會標(biāo)記為“進(jìn)入環(huán)境,并且給它一個標(biāo)示。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存,因為只要進(jìn)入到了相應(yīng)的環(huán)境,那么我們的瀏覽器就有可能用到它們,而當(dāng)變量離開環(huán)境時。則將其標(biāo)記為離開環(huán)境;

垃圾收集器在運行的時候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記,然后,它會去掉環(huán)境中的變量及被環(huán)境中的變量引用的變量的標(biāo)記。而在此之后再被加上離開環(huán)境時標(biāo)記的變量講被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無法訪問到這些變量了,最后,垃圾收集器完成內(nèi)存的清除工作。銷毀哪些帶標(biāo)記的值,并回收他們所占用的內(nèi)存空間。

內(nèi)存空間

  • JavaScript的執(zhí)行上下文生成之后,會創(chuàng)建一個叫做變量對象的特殊對象,JavaScript的基礎(chǔ)數(shù)據(jù)類型往往都會保存在變量對象中。
var a = 20;
var b = a;
b = 30;

// 這時a的值是20
  • JS的引用數(shù)據(jù)類型的值是保存在堆內(nèi)存中的對象。JavaScript不允許直接訪問堆內(nèi)存中的位置,因此我們不能直接操作對象的堆內(nèi)存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。因此,引用類型的值都是按引用訪問的。
var m = { a: 10, b: 20 }
var n = m;
n.a = 15;

// 這時m.a的值是15

按值傳遞

按值傳遞就是把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),就和把值從一個變量復(fù)制到另一個變量一樣。

var value = 1;
function foo(v) {
    v = 2;
    console.log(v); //2
}
foo(value);
console.log(value) // 1

當(dāng)傳遞 value 到函數(shù) foo 中,相當(dāng)于拷貝了一份 value,假設(shè)拷貝的這份叫 _value,函數(shù)中修改的都是 _value 的值,而不會影響原來的 value 值。

按引用的副本傳遞(按值傳遞)

按引用傳遞,就是傳遞對象的引用,函數(shù)內(nèi)部對參數(shù)的任何改變都會影響該對象的值,因為兩者引用的是同一個對象。

var obj = {
    value: 1
};
function foo(o) {
    o.value = 2;
    console.log(o.value); //2
}
foo(obj);
console.log(obj.value) // 2

按引用傳遞是傳遞對象的引用,而函數(shù)中參數(shù)是傳遞對象的引用的副本!

var obj = {
    value: 1
};
function foo(o) {
    o = 2;
    console.log(o); //2
}
foo(obj);
console.log(obj.value) // 1

修改 o.value,可以通過引用找到原值,但是直接修改 o,并不會修改原值。

結(jié)論

參數(shù)如果是基本類型是按值傳遞,如果是引用類型按引用的副本傳遞。

但是因為拷貝副本也是一種值的拷貝,所以在高程中也直接認(rèn)為是按值傳遞

所以ECMAScript中所有函數(shù)的參數(shù)都是按值傳遞的。

參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第1章 JavaScript 簡介 JavaScript 具備與瀏覽器窗口及其內(nèi)容等幾乎所有方面交互的能力。 歐洲...
    力氣強(qiáng)閱讀 1,281評論 0 0
  • 有人說過,很多彎路到最后都成了直路,所有的坑到最后也都成了坦途;所謂的直路和坦途并不是擺在眼前的,都是不斷的的...
    老衲法號一眉道人閱讀 1,452評論 0 4
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,755評論 11 349
  • 其實你一次次的這樣真的不想我的感受 其實說來還是不來根本不用問我,你的行動就是導(dǎo)向 其實用二十四小時就能知道三天不...
    _你的貓閱讀 262評論 0 0

友情鏈接更多精彩內(nèi)容