ES6之塊級作用域

来源:http://www.cnblogs.com/giggle/archive/2016/06/13/5572006.html
-Advertisement-
Play Games

ES6中提供了塊級作用域,分別是let和const,該隨筆分別介紹了它們 ...


一、前言

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

  1、  全局作用域;

  2、  函數作用域。

正是因為有這兩種作用域,所以在JavaScript中出現一術語--“變數提升(hoisting)”。

如下:

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

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

 

之所以為’undefined’,原因就在於‘變數提升’,在進入func函數時,將所有通過var聲明的變數置前並賦予undefined的值。

但,ES6的到來,為我們提供了‘塊級作用域’。且‘塊級作用域’並不影響var聲明的變數。

What?‘塊級作用域’又不影響var聲明的變數?!!

是的,var聲明的變數的性質和原來一樣,還是具有‘變數提升’的特性。而‘塊級作用域’通過新增命令let和const來體現。

下麵,我們透過新增的let和const命令,協同感受下ES6的塊級作用域。

註:由於let和const屬於ES6,所以都必須使用嚴格模式,否則會報錯。

如下:

let test;

在node環境下,執行代碼:

二、let命令

什麼是let呢?

let和var差不多,都是用來聲明變數的。區別就在於:

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

  2、  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環境下,執行上述代碼結果如下:

 

三、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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前幾天,舍友去某互聯網公司面前端研發工程師。回來後,他就跟我們聊了下麵試官給他出的題。其中,有一道題是“如何實現iframe高度的自適應?”。好吧,我承認,我聽到iframe這個詞的第一反應就是:這個東西性能差、搜索引擎不友好等等。由於這樣的偏見,還真沒有好好研究一下iframe。其實,iframe ...
  • every():對數組每一項都遍歷,然後每一項都符合要求的話則返回true,否則就返回false some():對數組每一項都遍歷,其中有一項符合要求則返回true,否則返回false filter():對數組的每一項都遍歷,返回其中要求的元素組成的數組 map():對數組每一項都遍歷並且運行給定的 ...
  • 之前的項目一直採用grunt來構建,然後用requirejs做模塊化,requirejs官方有提供grunt的插件來做壓縮合併。現在的項目切到了gulp,模塊化用起了seajs,自然而然地也想到了模塊合併壓縮的問題。然後一開始在解決這個問題的時候,並不是很順利,在npm上並沒有那種特別流行的專門用來... ...
  • 將近20年前,Javascript誕生的時候,只是一種簡單的網頁腳本語言。如果你忘了填寫用戶名,它就跳出一個警告。 如今,它變得幾乎無所不能,從前端到後端,有著各種匪夷所思的用途。程式員用它完成越來越龐大的項目。 Javascript代碼的複雜度也直線上升。單個網頁包含10000行Javascrip ...
  • 無論是提示框還是導航欄都能看到如上圖所示的帶有箭頭的框框,這種箭頭可以通過背景圖片或者是css來實現,本文介紹三種通過css實現帶箭頭的提示框。 通過border屬性思路:兩個三角形,通過定位使兩個三角形相差1px作為邊框。 CSS3 transfrom思路:先做一個兩條邊相同顏色的正方形,然後旋轉 ...
  • jQuery 3.0 在6月9日正式發佈了,3.0 也被稱為下一代的 jQuery 。這個版本從14年10月開始,其中發佈過一次beta 版(2016/1/14,)和候選版(2016/05/20)。一路走來,頗為不易。 文章目錄 一、Data淺析 jQuery 3.0 中的 Data 是內部使用的, ...
  • 1.什麼是HTML標記語言? HTML是表示網頁信息的符號標記語言。 2.HTML的標記和他的屬性 3.語法不區分字母大小寫 <HTML>、<Html>、<html>都是定義相同的標記,但是在編寫網頁的使用儘量使用小寫。 4.文檔註釋 註釋一段內容時使用"<!--"開始,以"-->"結束。 例如: ...
  • H5其實就是H4的一個增強版本,我們在利用H5進行網頁的構造會更簡便,標簽語義更簡潔明瞭。首先,我們要理解HTML4,它是HTML的標記+css2+JavaScript的一些基本應用,簡言之,就是API+語法;而H5無非就是在原先的基礎上面提供了一些新的功能。 1、H5的語義標簽 1):html 的 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...