文章目錄
-
- 基本類型和引用類型
- 執行環境
- 垃圾收集
- 類型檢測
- 關于const
基本類型和引用類型
- 基本類型是簡單的資料段,引用類型是可能有多個值組成的對象
- 基本類型包括:Undefined,null,Boolean,Number,String。這五種類型是按值通路的,是以可以操作儲存在變量中的值
- 引用類型是儲存在記憶體中的對象。JavaScript不允許直接通路記憶體中的位置,在操作對象時,實際上操作的是對象的引用而不是對象本身
- 對于引用類型的值,我們可以為其添加或删除屬性和方法。但是對于基本類型無法添加屬性,盡管不會報錯
- 複制過程
- 如果從一個變量向另一個變量複制基本類型的值,會建立一個新值,把該值複制到為新變量配置設定的位置上。即新舊變量完全獨立
- 如果複制引用類型,其實複制的是引用對象的指針。新舊變量同時指向存儲在堆中的一個對象。即,兩個變量實際上引用同一個對象
- 參數傳遞過程
- 所有的函數參數傳遞過程都是值傳遞。對于基本類型,傳遞的值即變量存儲的值,對于引用類型,傳遞的是指針的值。(因為引用類型的變量存儲的實際上就是指針)
- 在函數内部修改基本類型參數的值,不會反映到外部。
- 在函數内部修改引用類型參數的屬性,會反映到外部,但這并不意味是按引用傳遞
function setName(obj) { obj.name = "Nicolas"; obj = new Object(); obj.name = "Amy"; } var person = new Object(); setName(person); console.log(person.name); //Nicolas
- 檢測引用對象類型
variable instanceof constructor
: 檢測某個對象是不是某個類型的執行個體
所有引用類型的值都是
的執行個體object
執行環境
衆所周知,ES5以函數區塊來劃分變量環境。内部變量能通路外部變量,但外部變量不能通路内部變量(不考慮閉包),具體是怎麼實作的呢?
- 每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都儲存在這個對象中
- 全局環境是最外圍的一個執行環境。在Web浏覽器中,全局執行環境被認為是window對象,是以所有全局變量和函數都作為window對象的屬性和方法建立的。
- 每個函數有自己的執行環境。當執行流進入一個函數時,函數的環境會被推入一個環境棧中。而當函數執行之後,棧将其環境彈出,把控制權交給之前的執行環境。
- 當代碼在一個環境中執行時,會建立變量對象的一個作用域鍊。作用域鍊的用途,是保證對執行環境有權通路的所有變量和函數的有序通路。作用域鍊的前端,始終是目前執行的代碼所在環境的變量對象。作用域鍊的下一個變量對象來自外部環境,一直向外延伸,最後一個對象是全局執行環境的變量對象
- with可以修改作用域鍊。在作用域鍊的前端添加一個變量對象。
with 包含的區塊,就以function buildUrl() { var qs = "?debug==true"; with (location) { var url = href + qs; } return url; }
作為變量對象。其中location
指的是href
,location.href
通路的則是with外部的qs
qs
- JS沒有塊級作用域(環境)。作用域是按函數來劃分的。
- 使用var聲明的變量會被添加到最近的函數環境中。(是以上例中
的url可以被通路到)return url
垃圾收集
- 标記清除:常用。給目前不用的值加上标記,然後回收
- 引用計數:不常用。存在循環引用的問題
- 如何提高性能,優化記憶體占用:一旦資料不再有用,最好通過将其值設為null來釋放其引用—這個做法叫做解除引用
類型檢測
- typeof 用于基本資料類型的檢測
- instanceof 用于引用資料類型的檢測(檢查原型鍊)
關于const
引用類型,包括object,array,都是儲存在記憶體中,變量中存儲的實際上是這個對象的引用(指針)
是以就出現了以下問題
const變量可以更改屬性?
const yyy = [];
yyy = 10; //錯誤
yyy.push(1); //成功
原因為:
constant cannot change through reassignment
constant cannot be re-declared
when you’re adding to an array or object you’re not re-assignment or re-declaring the constant, it’s already declared and assigned, you’re just adding to the “list” that the constant points to.
是以以下代碼均能正常工作:
const x = {};
x.foo = 'bar';
console.log(x) // {foo: 'bar'}
const y = [];
y.push('foo');
console.log(y); // ['foo']