1. 程式人生 > >es5與es6的變數宣告和作用域的異同

es5與es6的變數宣告和作用域的異同

在es6沒出來之前,js的作用域只有兩種頂層作用域和函式作用域,但是es6的出現,讓js的變數作用域有了新的存在形式:塊級作用域

在瞭解塊級作用域之前,還是得先複習下es5的變數宣告與作用域

變數宣告:

我們都知道js使用var關鍵字來宣告一個變數,如果不使用var關鍵字來宣告變數就表示宣告的變數是頂層變數(雖然這不是一個嚴謹的寫法,在es5的嚴格模式下會丟擲異常)。當我們直接宣告一個變數的時候就相當於是在window下掛載了一個新變數。例如:

a = 1;
window.a = 1;
//上述兩種寫法是一樣的。但是在如下情況第一種寫法是錯誤的。

'use strict'
a = 1
; //Uncaught ReferenceError: a is not defined(…)

變數提升:

在js中所有由var宣告的變數都會提升到作用域的頂部進行宣告,然後再在宣告的地方進行賦值。還是直接看程式碼吧!

var a = 1;
function foo(){
    console.log(a);  //undefined;
    //因為該函式內重新聲明瞭一次a變數,雖然在當前語句的後面才a變數,但是變數宣告會被提升到當前函式作用域的頂部。
    //注意這裡只是將宣告提升到了頂部,而沒有進行賦值,賦值還是在宣告變數行進行,所有後面的console.log才會打印出3。
    var
a = 3; console.log(a); //3 } foo();

有一點需要注意的就是,var宣告函式變數時,和直接使用function定義函式時效果是不一樣的。var只能把變數名的宣告提前,而使用function定義函式時,函式的初始化也會被提前,所以不論你何時使用function宣告函式,只要有宣告呼叫時都不會產生錯誤,而使用var形式的函式表示式,在賦值之前呼叫都會找不到函式。

fun(); //Uncaught TypeError: fun is not a function(…)
var fun = function () {
    alert(1);
}

-----------
fun(); //1 function fun() { alert(1); }

還有一點就是重複使用同一函式名的兩個函式,後宣告的生效

function fun() {
    return 1;
}

console.log(fun());  //2

function fun() {
    return 2;
}

es6如何宣告變數:

es6引入了兩種新的宣告變數的方式:let與const。

  1. let
    使用let宣告的變數與var宣告的變數類似,唯一的區別就是隻能在當前塊級作用域中有用。先看看什麼是塊級作用域,所謂塊級作用域,就是當前的程式碼塊,簡單來說就是一對大括號中的內容就叫做塊級作用域,比如一個if語句中的內容,一個for迴圈中的內容。
{
    var  a = 1;
    let b = 2;
}

console.log(a); //1
console.log(b); //b is not defined(…)

再看一個例子:

if(true){
    let a = 1;
}

console.log(a); //a is not defined(…)

引入塊級作用域有很多好處,比如解決了之前for迴圈定義的變數造成全域性汙染的問題,而且不必再使用閉包來儲存必要的變數,因為各個程式碼塊的變數相互獨立,不會造成全域性變數的汙染。

//es5:
for(var i=0;i<5;i++){

}
console.log(i); //5


//es6:
for(let i=0;i<5;i++){

}
console.log(i); //i is not defined(…)
//es5:
var arr = []
for(var i=0;i<5;i++){
    arr[i] = function(){
        alert(i);
    }
}
arr[3](); //5


//es6:
let arr = []
for(let i=0;i<5;i++){
    arr[i] = function(){
        alert(i);
    }
}
arr[3](); //3
  1. const
    使用const宣告的變數與let宣告的變數類似,也只能在塊級作用域中有用,不同的是const宣告的變數是隻讀的,也就是宣告過後就不能被修改了。
const PI = 3.1415;
PI = 3; // Assignment to constant variable.

let與const沒有變數提升:

之前看到var宣告的變數都會提升到,但是使用let與const宣告的變數沒有這個特點。

{
    console.log(a); //a is not defined(…)
    let a = 1;

    -------

    console.log(b); //b is not defined(…)
    const b = 1;
}

如果在申明變數之前,就呼叫該變數就會產生錯誤(ReferenceError)。在上面的案例中let a之前我們呼叫了a變數,但是該變數是不可用的,我們把該變數不可用的區域叫做“暫時性死區”(temporal dead zone,簡稱TDZ)。這樣做也有好處,在沒有宣告變數之前就不能使用該變數從而可以減少一些程式碼執行的錯誤,像es5如果使用了也難以發現錯在哪裡。

不允許重複的變數宣告:

{
    let a = 1;
    let a = 2; //Identifier 'a' has already been declared
}

重複在同一個塊級作用域內宣告同一個變數會有語法錯誤。

es6為js的變數提供了兩種新的變數宣告方式(let與const),並且提供了新的塊級作用域。雖然這給之前js的靈活性帶來了一定的限制,但是這根本不算什麼,太靈活也會造成很多的混亂,塊級作用域的引入讓我們不必再使用閉包的方式來儲存一些變量了。

相關推薦

es5es6變數宣告作用異同

在es6沒出來之前,js的作用域只有兩種頂層作用域和函式作用域,但是es6的出現,讓js的變數作用域有了新的存在形式:塊級作用域。 在瞭解塊級作用域之前,還是得先複習下es5的變數宣告與作用域。 變數宣告: 我們都知道js使用var關鍵字來宣告一個變數,如

php變數型別作用

一、變數和常量 變數 變數以 $ 符號開始,後面跟著變數的名稱 變數名必須以字母或者下劃線字元開始 變數名只能包含字母數字字元以及下劃線(A-z、0-9 和 _> ) 變數名不能包含空格 變數名是區分大小寫的($y 和 $Y 是兩個不同的變數)

Typescript學習筆記(三)變數宣告作用

ts的變數宣告有var,let和const,這尼瑪完全跟es6一樣嘛。就稍微介紹一下。 大多數js開發者對於var很熟悉了,原生js裡沒有塊級作用域,只有函式作用域和全域性作用域,還存在var的變數提升的問題,導致一些不熟悉js的開發者會發現一些怪異事件。點選檢視關於es6的let與const

ES5ES6變數宣告比較

ES5變數宣告之var: 1.var宣告的變數,會出現宣告提前的問題,內層變數覆蓋外層變數 例如:var tmp = now Date(); function test() { console.log(tmp); // undefined 宣告提前     if(true){

JS中最經典的全域性變數區域性變數問題(1、作用作用鏈 2、變數宣告提前)

var a = 10; function test(){ a = 100; console.log(a); console.log(this.a); var a; console.log(a); } test(); 1、程式的執行結果為:100

ES6】塊級作用函式宣告

塊級作用域與函式宣告 ES5 規定,函式只能在頂層作用域和函式作用域之中宣告,不能在塊級作用域宣告。 // 情況一 if (true) { function f() {} } // 情況二 try { function f() {} } catch(e) { // ..

Java變數宣告、初始化作用

一.Java變數的宣告 在 Java 程式設計中,每個宣告的變數都必須分配一個型別。宣告一個變數時,應該先宣告變數的型別,隨後再宣告變數的名字。下面演示了變數的宣告方式。 double salary; int age; Boole

JavaScript中var let的區別,四個概念變數提升,作用,重複宣告,暫時死區以及從生命週期去看它

前言 今天無意當中遇到了js中的變數宣告,發現除了var居然還有let宣告方法,比較新奇,特地記錄下來它們兩者的區別!絕對能讓你理解清楚,PS 後面有重頭戲 思路 主要從四個角度來講述它們的區別 變數提升 作用域 重複宣告 暫時死區 變數提

jquery的變數作用作用鏈的使用

  1、函式變數的作用域有全域性變數和區域性變數兩種,全域性變數寫在函式的最前面,區域性變數寫在函式體內,區域性變數省略了var 也就預設成為了全域性變數!     2、函式體內部可以讀取到函式外的變數,而函式外不能讀取到函式內的變數! 每次呼叫viewM

變數作用以及記憶體問題

在javascript中有五種基本型別:string/boolean/null/undefind/number,一種引用型別:object   記憶體中的未知: 1/因為基本型別資料是簡單型別資料執行時建立在棧記憶體中即可,2/object是複雜型別資料佔記憶體多所以儲存在堆記憶體中以便於其他變

js學習筆記-第二章變數作用記憶體問題-執行環境作用

//執行環境:執行環境(execution context,為簡單起見,有時也稱為“環境”)是 JavaScript 中最為重要的一個概念。執行環境定義了變數或函式有權訪問的其他資料,決定了它們各自的行為 //變數物件:。每個執行環境都有一個與之關聯的變數物件(variable object

Python的變數作用、名稱空間作用的區別、This inspection detects shadowing names defined in outer scopes警告解決

Python的變數作用域: L(local)區域性作用域: 區域性變數:包含在def關鍵字定義的函式中,即在函式中定義的變數。每當函式被呼叫時都會建立一個新的區域性作用域。在函式內部的變數宣告,除非特別的使用global關鍵字宣告為其全域性變數,否則均預設為區域性變數。

java炒冷飯系列11 方法作用內的內部類 匿名內部類

在方法和作用域內的內部類 到目前為止,讀者所看到的只是內部類的典型用途。通常,如要所讀、寫的程式碼包含了內部類,那麼它們都是“平凡的”內部類,簡單並且容易理解。然而,內部類的語法覆蓋了大量其他的更加難以理解的技術。例如,可以在一個方法裡面或者在任意的作用域內定

【譯】終極指南:變數提升、作用閉包

原文作者:Tyler McGinnis 原文連結:tylermcginnis.com/ultimate-gu… 文中部分連結可能需要梯子。 歡迎批評指正。 說出來可能嚇你一跳,在我看來,理解Javascript的最重要最基本的思路就是理解執行上下文。吃透了執行上下文,你就能更好地學

C語言常量以及變數型別,儲存型別作用

變數 其值可以改變的量稱為變數。一個變數應該有一個名字,在記憶體中佔據一定的儲存單元。變數定義必須放在變數使用之前。一般放在函式體的開頭部分。要區分變數名和變數值是兩個不同的概念。 變數定義的一般形式為:    型別說明符  變數名, 變數名, ...;在書寫變數定義時,應注意以下幾點: 允許在一個型

ES6 變數宣告賦值:值傳遞、淺拷貝深拷貝

ES6 變數宣告與賦值:值傳遞、淺拷貝與深拷貝詳解轉載於王下邀月熊_Chevalier的現代 JavaScript 開發:語法基礎與實踐技巧系列文章。 變數宣告與賦值 ES6 為我們引入了 let 與 const 兩種新的變數宣告關鍵字,同時也引入了塊作用域;本文

ES6 變數宣告賦值:值傳遞、淺拷貝深拷貝詳解

變數宣告與賦值 ES6 為我們引入了 let 與 const 兩種新的變數宣告關鍵字,同時也引入了塊作用域;本文首先介紹 ES6 中常用的三種變數宣告方式,然後討論了 JavaScript 按值傳遞的特性以及多種的賦值方式,最後介紹了複合型別拷貝的技巧。 變數宣告

變數的生命期作用

一、變數的作用域:是從編寫程式碼的角度,每個變數都有一個有效的範圍。在這個範圍之內這個變數是可以訪問的。         可以訪問上一層級的變數 二、區域性變數的作用域:(1)從定義之處生效(2)到大括號結束失效(該變數所

PHP 偽變數($this->) 作用操作符(::) 的是使用

<?php header("Content-Type: text/html; charset=utf-8"); /** * */ class Test

js面試筆試---理解 JavaScript 作用作用

任何程式設計語言都有作用域的概念,簡單的說,作用域就是變數與函式的可訪問範圍,即作用域控制著變數與函式的可見性和生命週期。在JavaScript中,變數的作用域有全域性作用域和區域性作用域兩種。   1.  全域性作用域(Global Scope)   在程式碼中任何地方