JavaScript高級程序設計筆記 - 第四章 變量 做用域 內存問題

4.1 基本類型和引用類型的值

  • 基本類型: 簡單的數據段
  • 引用類型: 指那些可能有多個值構成的對象, 指保存在內存中的對象

4.1.2 複製變量值

  • 除了保存的方式不一樣以外,在從一個變量向另外一個變量複製基本類型值和引用類型值時,也存在不一樣
  1. 基本類型: 若是從一個變量向另外一個變量複製基本類型的值,會在變量對象上建立一個新值,而後把該值複製到爲新變量分配的位置上 javascript

    基本類型複製

  2. 引用類型: 當從一個變量向另外一個變量複製引用類型的值時,一樣也會將存儲在變量對象中的值複製一份放到爲新變量分配的空間中。不一樣的是,這個值的副本其實是一個指針,而這個指針指向存儲在堆中的一 個對象。複製操做結束後,兩個變量實際上將引用同一個對象。所以,改變其中一個變量,就會影響另 一個變量 前端

    引用類型複製

4.1.3 傳遞參數

  • 傳遞基本類型
function addTen(num) {
        num += 10
        return num;
    }
    var count = 20
    var result = addTen(count)
    console.log(count) // 20, 沒有變化
    console.log(result) // 30
複製代碼
  • 傳遞引用類型
function setName(obj) {
        obj.name = "Nicholas"
    }
    var person = new Object()
    setName(person);
    console.log(person.name) // "Nicholas"
複製代碼
// 爲了證實對象是按值傳遞的
    function setName(obj) {
        obj.name = "Nicholas"
        obj = new Object()
        obj.name = "Greg"
    }
    var person = new Object()
    setName(person);
    console.log(person.name) // "Nicholas"
複製代碼

4.1.4 檢測類型

  • typeof: 檢測基本數據類型, string, number, boolean, undefined,object(對象, null)
  • instanceof: 檢測引用類型, 什麼類型的對象, 全部引用類型的值都是 Object 的實例

4.2 執行環境及做用域

  • 執行環境定義了**函數和變量有權訪問的其餘數據, 每一個執行環境都有與之對應的變量對象**, 環境中定義的變量和函數都定義在這個對象中
  • 全局環境是最外層的執行環境, 在web瀏覽器中被認爲是**windows**對象,由於全部的全局變量和函數都做爲window 對象的屬性和方法,執行環境中的代碼執行完畢後,該環境被銷燬,其中的全部變量和函數定義也隨之銷燬
  • 每一個函數都有本身的執行環境, 當執行流進入某個函數時, 函數的執行環境就會就會進入環境棧, 函數執行完畢後,環境出棧, 把控制權交給以前的執行環境
  • 當代碼在某個環境中執行, 會建立變量對象的**做用域鏈, 做用域鏈保證對執行環境有權訪問的全部變量和函數的有序訪問, 做用域鏈的前端始終是當前執行環境的變量對象,最後一個對象是全局環境中的變量對象**, 若是這個環境是函數,則將其活動對象做爲變量對象. 活動對象最開始只包含arguments對象(全局環境不存在)
var color = 'blue'
    function changeColor() {
        if (color === 'blue') {
            color = 'red'
        } else {
            color = 'blue'
        }
    }
    changeColor()
    console.log(color)
    
    // changeColor() 函數中包含本身的變量對象和全局環境的變量對象
複製代碼
var color = "blue";
        function changeColor(){
            var anotherColor = "red";
            function swapColors(){
                var tempColor = anotherColor;
                anotherColor = color;
                color = tempColor;
                    // 這裏能夠訪問color、anotherColor和tempColor 
        }
            // 這裏能夠訪問color和anotherColor,但不能訪問tempColor
            swapColors();
    }
    // 這裏只能訪問color 
    changeColor();
複製代碼

函數的做用域鏈圖 java

4.2.1 延長做用域鏈

當執行流進入下列任何一個語句時,做用域鏈就會獲得加長:web

  • try-catch語句的catch塊
  • with語句

這兩個語句都會在做用域鏈的前端添加一個變量對象,對with語句來講,會將指定的對象添加到做用域鏈中.對catch語句來講,會建立一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明windows

4.2.2 沒有塊級做用域

javascript沒有塊級做用域瀏覽器

if (true) {
        var color = "blue"
    }
    console.log(color) // blue
    // javascript中, if 語句中的變量聲明會將變量添加到當前的執行環境中
複製代碼
function func() {
        if (true) {
            var color = "blue"
        }
        console.log(color) 
    }
    func() // blue
    console.log(color) // error
    // color 添加到了func執行環境中,並無添加到window執行環境中
複製代碼
for (var i = 0; i < 10; i++) {
        ......
    }
    console.log(i) // 10
複製代碼
  • 聲明變量 var 聲明的變量會被添加到最近的環境中,在**函數內部就是最近的環境就是局部環境; 在with語句中就是函數環境, 若是初始化變量沒有使用var則被添加到全局環境**中
function add(num1, num2) {
        var sum = num1 + num2
        return sum
    }
    var result = add(10, 20) // 30
    console.log(sum) // error
複製代碼
function add(num1, num2) {
        sum = num1 + num2
        return sum
    }
    var result = add(10, 20) // 30
    console.log(sum) // 30
複製代碼
  • 標識符查詢 在某個環境中爲了讀取或者寫入而引入一個標識符,必須經過搜索來肯定該標識符的意思, 搜索過程從當前做用域前端開始逐步向上查找直至全局做用域爲止
var color = 'blue'
    function getColor() {
        return color
    }
    console.log(getColor()) // 'blue'
複製代碼

搜索過程以下 函數

搜索過程以下
相關文章
相關標籤/搜索