ES6-塊級做用域

在ECMAScript6(如下簡稱ES6)以前,ECMAScript的做用域只有兩種:node

  一、  全局做用域;閉包

  二、  函數做用域。ide

正是由於有這兩種做用域,因此在JavaScript中出現一術語--「變量提高(hoisting)」。函數

以下:spa

function func(){
    console.log(test);
    var test = 1;
};
func();

在node環境執行上述代碼,結果爲:3d

 

之因此爲’undefined’,緣由就在於‘變量提高’,在進入func函數時,將全部經過var聲明的變量置前並賦予undefined的值。code

但,ES6的到來,爲咱們提供了‘塊級做用域’。且‘塊級做用域’並不影響var聲明的變量。blog

What?‘塊級做用域’又不影響var聲明的變量?!!ip

是的,var聲明的變量的性質和原來同樣,仍是具備‘變量提高’的特性。而‘塊級做用域’經過新增命令let和const來體現。作用域

下面,咱們透過新增的let和const命令,協同感覺下ES6的塊級做用域。

注:因爲let和const屬於ES6,因此都必須使用嚴格模式,不然會報錯。

以下:

let test;

在node環境下,執行代碼:

2、let命令

什麼是let呢?

let和var差很少,都是用來聲明變量的。區別就在於:

  一、  let聲明的變量只在所處於的塊級有效;

  二、  let沒有‘變量提高’的特性,而是‘暫時性死區(temporal dead zone)’特性。

下面將一一講解。

1、let聲明的變量只在塊級有效。

以下:

複製代碼
'use strict';
function func(args){
    if(true){
        //let聲明i
        let i = 6;
        //在if內打印i值
        console.log('inside: ' + i);
    }
    //在if外,再次打印i值
    console.log('outside: ' + i);
};
func();
複製代碼

在node環境中執行上述代碼,結果以下:

經過demo,咱們能夠清楚的看見,在第二次(if外)打印i值時,是報錯的。

這由於let聲明的變量i是屬於if內的塊級做用域;而不是像var同樣。

2、let沒有‘變量提高’的特性,而卻有‘暫時性死區(temporal dead zone)’的特性。

以下:

複製代碼
'use strict';
function func(){
    //在let聲明前,打印i
    console.log(i);
    let i;
};
func();
複製代碼

在node環境下執行上述代碼,結果以下:

在let聲明變量前,使用該變量,它是會報錯的,而不是像var那樣會‘變量提高’。

其實說let沒有‘變量提高’的特性,不太對。或者說它提高了,可是ES6規定了在let聲明變量前不能使用該變量。

以下:

複製代碼
'use strict';
var test = 1;
function func(){
    //打印test的值
    console.log(test);
    let test = 2;
};
func();
複製代碼

在node環境下執行上述代碼,結果以下:

若是let聲明的變量沒有變量提高,應該打印’1’(func函數外的test);而他卻報錯,說明它是提高了的,只是規定了不能在其聲明以前使用而已。咱們稱這特性叫「暫時性死區(temporal dead zone)」。且這一特性,僅對遵循‘塊級做用域’的命令有效(let、const)。

關於let,最後再經過一個經典案例,體驗下。

以下:

複製代碼
var arr = [];
for(var i = 0; i < 2; i++){
    arr[i] = function(){
        console.log(i);
    };
};
arr[1]();
複製代碼

arr[1]()會輸出2,緣由是var聲明的變量會變量提高,且當執行arr[1]函數時,i取自於父函數的i,而此時i已經變爲2了,因此就會打印2咯。

之前的經常使用作法是,利用閉包特性。以下:

複製代碼
var arr = [];
for(var i = 0; i < 2; i++){
    arr[i] = (function(i){
        return function(){
            console.log(i);
        };
    }(i));
};
arr[1]();
複製代碼

又或者屬性方式:

複製代碼
var arr = [];
for(var i = 0; i < 2; i++){
    (arr[i] = function self(){
        console.log(self.x);
    }).x = i;
};
arr[1]();
複製代碼

如今有了let,它聲明的變量做用域爲塊級,因此,咱們也能夠利用let來達到一樣的效果。

以下:

複製代碼
'use strict';
var arr = [];
for(let i = 0; i < 2; i++){
    arr[i] = function(){
        console.log(i);
    };
};
arr[1]();
複製代碼

在node環境下,執行上述代碼結果以下:

 

3、const命令

const命令與let命令同樣,聲明的變量,其做用域都是塊級。

因此const遵循的規則與let相差無二,只是,const是用來聲明恆定變量的。

且,用const聲明恆定變量,聲明的同時就必須賦值,不然會報錯。

以下:

複製代碼
'use strict';
function func(){
    const PI;
    PI = 3.14;
    console.log(PI);
};
func();
複製代碼

在node環境下,執行上述代碼結果以下:

正確的方式爲,聲明就得賦值。

如:

const PI = 3.14
相關文章
相關標籤/搜索