天天看點

《Javascript進階程式設計》閱讀筆記 ----第4章

文章目錄

    • 基本類型和引用類型
    • 執行環境
    • 垃圾收集
    • 類型檢測
    • 關于const

基本類型和引用類型

  1. 基本類型是簡單的資料段,引用類型是可能有多個值組成的對象
  2. 基本類型包括:Undefined,null,Boolean,Number,String。這五種類型是按值通路的,是以可以操作儲存在變量中的值
  3. 引用類型是儲存在記憶體中的對象。JavaScript不允許直接通路記憶體中的位置,在操作對象時,實際上操作的是對象的引用而不是對象本身
  4. 對于引用類型的值,我們可以為其添加或删除屬性和方法。但是對于基本類型無法添加屬性,盡管不會報錯
  5. 複制過程
    1. 如果從一個變量向另一個變量複制基本類型的值,會建立一個新值,把該值複制到為新變量配置設定的位置上。即新舊變量完全獨立
    2. 如果複制引用類型,其實複制的是引用對象的指針。新舊變量同時指向存儲在堆中的一個對象。即,兩個變量實際上引用同一個對象
      《Javascript進階程式設計》閱讀筆記 ----第4章
  6. 參數傳遞過程
    1. 所有的函數參數傳遞過程都是值傳遞。對于基本類型,傳遞的值即變量存儲的值,對于引用類型,傳遞的是指針的值。(因為引用類型的變量存儲的實際上就是指針)
    2. 在函數内部修改基本類型參數的值,不會反映到外部。
    3. 在函數内部修改引用類型參數的屬性,會反映到外部,但這并不意味是按引用傳遞
    function setName(obj) {
      obj.name = "Nicolas";
      obj = new Object();
      obj.name = "Amy";
    }
    
    var person = new Object();
    setName(person);
    console.log(person.name); //Nicolas
               
  7. 檢測引用對象類型

    variable instanceof constructor

    : 檢測某個對象是不是某個類型的執行個體

    所有引用類型的值都是

    object

    的執行個體

執行環境

衆所周知,ES5以函數區塊來劃分變量環境。内部變量能通路外部變量,但外部變量不能通路内部變量(不考慮閉包),具體是怎麼實作的呢?

  1. 每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都儲存在這個對象中
  2. 全局環境是最外圍的一個執行環境。在Web浏覽器中,全局執行環境被認為是window對象,是以所有全局變量和函數都作為window對象的屬性和方法建立的。
  3. 每個函數有自己的執行環境。當執行流進入一個函數時,函數的環境會被推入一個環境棧中。而當函數執行之後,棧将其環境彈出,把控制權交給之前的執行環境。
  4. 當代碼在一個環境中執行時,會建立變量對象的一個作用域鍊。作用域鍊的用途,是保證對執行環境有權通路的所有變量和函數的有序通路。作用域鍊的前端,始終是目前執行的代碼所在環境的變量對象。作用域鍊的下一個變量對象來自外部環境,一直向外延伸,最後一個對象是全局執行環境的變量對象
  5. with可以修改作用域鍊。在作用域鍊的前端添加一個變量對象。
    function buildUrl() {
      var qs = "?debug==true";
      with (location) {
        var url = href + qs;
      }
      return url;
    }
               
    with 包含的區塊,就以

    location

    作為變量對象。其中

    href

    指的是

    location.href

    qs

    通路的則是with外部的

    qs

  6. JS沒有塊級作用域(環境)。作用域是按函數來劃分的。
  7. 使用var聲明的變量會被添加到最近的函數環境中。(是以上例中

    return url

    的url可以被通路到)

垃圾收集

  1. 标記清除:常用。給目前不用的值加上标記,然後回收
  2. 引用計數:不常用。存在循環引用的問題
  3. 如何提高性能,優化記憶體占用:一旦資料不再有用,最好通過将其值設為null來釋放其引用—這個做法叫做解除引用

類型檢測

  1. typeof 用于基本資料類型的檢測
  2. 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']
           

繼續閱讀