JavaScript 環境和做用域

做用域

1. 全局環境

window: JS的全局執行環境,頂層對象。this指針在全局執行環境時就指向window。javascript

console.log(this===window); //true

2. 局部環境

什麼狀況會具備局部環境?
答: function聲明(包括常規聲明,箭頭函數,匿名函數)的花括號{}內部會造成局部環境。java

let a = 1;
(()=>{let a = 2;})();
(function(){let a = 2;})();
function f1()
{
    let a = 3;
}
f1();

局部環境有什麼特徵?
答: 局部環境是運行在全局環境下的一個獨立環境,局部環境能夠嵌套。函數

局部環境和全局環境的關係?
答: 局部環境能夠經過做用域鏈訪問遞歸上級局部環境和最終全局環境中的資源。this

3. 做用域鏈

從當前環境的arguments對象開始,到包含該環境的下一個環境的全部變量,一直到全局環境的變量,造成一個做用域鏈。指針

var color = "blue";
function changeColor(){
    var anotherColor = "red";
    function swapColors(){
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        console.log(this);
        // 這裏能夠訪問color、anotherColor 和tempColor
    }
    // 這裏能夠訪問color 和anotherColor,但不能訪問tempColor
    swapColors();
}
// 這裏只能訪問color
changeColor();

以下圖:code

window
  |__color
  |__changeColor()
    |__anotherColor
    |__swapColors()
      |__tempColor對象

注意:function內部不帶類型的變量聲明將會被定義到全局環境遞歸

function Fun(){
    var a = 1;
    b = 2;
}
Fun();
console.log(a);//not defined
console.log(b);//2

4. 沒有塊級做用域 VS 有塊級做用域

塊級做用域:由花括號{}所造成的做用域ip

  • ES5之前沒有塊級做用域
  • ES6使用let和const,則具備塊級做用域特性
//a.js
var a = 1;
if(true)//if語句後的{}並不會造成塊級做用域,其中的代碼仍是運行在頂級做用域
{
    var a = 2;//變量覆蓋
}
console.log(a);//2
//b.js
if(true)
{
    var a = 1;//定義到全局
    let b = 2;//塊級內部有效
    const c = 3;//塊級內部有效
}
console.log(a); //1
console.log(b); //not defined
console.log(c); //not defined
//c.js
var a = 0;
(function fun1()
{
    var a = 1;
    let b = 2;
    const c = 3;
})()
console.log(a); //0
console.log(b); //not defined
console.log(c); //not defined

5. 變量提高

變量提高:在指定做用域裏,從代碼順序上看是變量先使用後聲明,但運行時變量的 「可訪問性」 提高到當前做用域的頂部,其值爲 undefined ,沒有 「可用性」。
函數提高:同理,但只有函數聲明式才存在函數提高,匿名函數和函數引用不會資源

看個例子就清楚了:

var i = 5;
function func() {
    console.log(i);//undefined
    var i = 6;
    console.log(i);//6
}
func();
//根據JS引擎的編譯,實際上的代碼運行以下
var i = 5;
function func() {
    var i;
    console.log(i);//undefined
    i = 6;
    console.log(i);//6
}
func();
//函數提高以下
console.log(f1()); //aa
console.log(f2); //undefined
function f1() {console.log('aa')}
var f2 = function() {}
相關文章
相關標籤/搜索