ES6入門(一)


ES6入門 (一)

let 和 const 命令

  • 定義:let 和 const 都是ES6 當中聲明變量的關鍵字

let

定義

let 用法與var 相似

注意事項

塊級作用域

我們使用let 會創建一個塊級作用域,這個變量只能在這個塊級作用域當中使用。那么問題來了,什么是塊級作用域呢?在我們學習js的時候相信大家都知道什么是 局部作用域 什么是 全局作用域 。下面我們例子說明一下

<script>
    let a = 5;    //當我們在全局范圍內聲明一個變量的時候,這個變量的塊級作用域就是全局作用域
    function fn1(){
        let b = 10   //當我們在局部范圍內聲明一個變量,他的塊級作用域就是局部作用域
    }
</script>
  1. ES5當中 內存變量可能會覆蓋外層變量
var a = 'abc';

function f() {
    // 函數內部變量提升 相當於 var a 的聲明
    console.log(a);
    if(false) {
        var a = 'hello,world'
    }
}
f() // undefined

上面代碼的原意是,if代碼塊的外部使用外層的tmp變量,內部使用內層的tmp變量。但是,函數f執行后,輸出結果為undefined,原因在於變量提升,導致內層的tmp變量覆蓋了外層的tmp變量。

  1. 用來計數的循環變量泄露成全局變量
var s = 'hello';
for(var i=0;i<s.length;i++){
    console.log(s[i])
}
console.log(i) //5
  1. ES5中 函數只能在頂層的作用域和函數作用域之中聲明,不能在塊級作用域當中聲明。而ES6當中允許在塊級作用域之中聲明函數。但是函數聲明語句的行為類似於 let,在塊級作用域之外不可引用
不存在變量提升

如果你已經學過 js 並且有一定的js 基礎 那么你對 變量提升 一定不陌生。我們都知道如果按正常邏輯,我們必須聲明一個變量,然后才應該可以使用他,而變量提升就可以讓我們在聲明變量之前就使用這個變量(只是不會報錯)

變量提升簡單來說:就是在js 代碼解析的過程當中 我們會把所有的聲明的變量提升到這個變量所在作用域的第一行,也就是說我們在給變量賦值之前使用變量的時候不會報錯,因為變量提升讓變量的聲明體現到了代碼解析的最前面。

而我們使用let 聲明變量的時候,不存在變量提升。也就是說我們在聲明這個變量之前不可以使用這個變量否則就會報錯

// 變量提升 相當於 var a 提前聲明了一個變量 只有經歷賦值操作才可以有值
console.log(a) // undefined
var a = 2  
console.log(a) // 2

console.log(b) // 報錯
let b = 2
console.log(b) // 2
let的特點就是存在暫時性死區

只要塊級作用域內存在 let 命令,它所聲明的變量就 “綁定” (binding)這個區域,不再受外部的影響。

var a = 10;
if (true) {
    a = 5; // ReferenceError
    let a; 
}

在這個代碼中, 存在一個全變量 a , 但是在 if 塊級作用域內又聲明了一個局部變量a,導致局部變量a被綁定在這個塊級作用域,所以在let聲明變量前,使用這個局部變量都會報錯。

ES6 明確規定,如果區塊中存在letconst命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。

總之,在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)

if(true) {
    a = 'abc';   // ReferenceError
    console.log(a)  // ReferenceError
    
    let a ;  //遇到了變量的聲明 暫時性死區結束
    console.log(a)  //已經遇到了變量的聲明,這個時候打印他 a的值是 undefined
    a = 123;
    console.log(a) // 結果 123
}
特殊情況的暫時性死區 之 ES6函數存在默認值情況
function fn1(x=y,y=2) {
    return [x,y]
}
fn1() //報錯

如果你是初次介紹es6 我可以簡單給你先介紹一下es6中函數存在默認值的情況。函數的默認值呢,是在我們使用函數並且沒有給函數傳遞實參的時候,這時他的參數的值就等於我們給這個參數設置的默認值

在上述代碼中 參數x默認值等於另一個參數 y 但是在這個時候 y 還沒有聲明,屬於 暫時性死區。

function fn1(x=2,y=5) {
    return [x,y]
}
fn1() //  //[2,5] 因為我們沒有給這個函數傳遞實參  所以參數的默認值就起了作用

fn1(3) // [3,5]

fn1(3,4) //[3,4]

默認參數的作用域

一旦設置了參數的默認值,函數進行聲明初始化的時候,參數會形成一個單獨的作用域。等到初始化結束,這個作用域就會消失 。

var x = 1;

function f(x,y=x) {
    console.log(y)
}

f(2) // 2

在上述代碼當中,參數y的默認值等於變量x。調用這個函數的時候,參數形成了一個單獨的作用域 ,在這個作用域里面,函數的一個參數指向的是調用這個函數傳遞的實參2

 let x = 2
 function f1(y=x){
 	let x = 3;
 	console.log(y)
 }
f1() // 2 

在上述代碼中同樣涉及到一個高級概念 作用域鏈。與上面例子一樣,調用這個函數的時候y=x 形成了一個單獨的作用域他是局部作用域,因為在這里x的值不存在,所以根據作用域鏈,他會向上一層作用域尋找x直到找到他 所以這個例子中 參數y的默認值x 是全局作用域當中聲明的變量x

不允許重復聲明變量
function fn2() {
    let a = 10;
    let a = 1;  // 報錯 
}
fn2()

function fn3(x) {
    let x;
}
fn3() // 報錯

function fn4(x) {
    {
        let x ;
    }
}
fn4() // 不報錯 

const 關鍵字

定義:

const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。

注意事項

const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。

const命令的本質

const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。但對於復合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。

const foo = {};

// 為 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123

// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM