乐趣区

关于程序员:快速了解-ES6-的let与const

ECMAScript 变量是涣散类型的,意思是变量能够用于保留任何类型的数据。每个变量只不过是一个用于保留任意值的命令占位符。在 ECMAScript 6 之前,申明变量应用 var 关键字,ECMAScript 6 新增了 constlet 关键字用以申明变量。

var

应用 var 关键字申明变量:

var msg;    // 不初始化时,变量保留一个非凡值 undefined
var msg = "Hello";    // 初始化
msg = 3.14;    // 能够扭转保留的值和值的类型,但不举荐 

作用域

var 申明的变量的作用域是函数作用域,在函数退出时销毁变量:

function test() {var msg = "Hello";}
test();
console.log(msg); // ReferenceError: msg is not defined

然而省略 var 会创立全局变量:

function test() {msg = "Hello";}
test();
console.log(msg); // Hello

但这样操作会使得全局变量很难保护,不举荐这样做。

var 申明晋升

var 申明变量之前调用变量不会报错,因为 var 申明的变量会主动晋升到函数作用域顶部:

function test() {console.log(name);
    var name = "小明";
}
test(); // undefined

let

letvar 的作用差不多,但也有着十分重要的区别。最次要的区别是:let 申明变量的作用域是块作用域,var 申明变量的作用域是函数作用域。

function varScope() {if (true) {
        var name = "var name";
        console.log(name);    // var name
    }
    console.log(name);    // var name
}
function letScope() {if (true) {
        let name = "let name";
        console.log(name);    // let name 
    }
    console.log(name);    // ReferenceError: name is not defined
}

从下面的例子中晓得,let 关键字申明变量的作用域仅限于块外部。块作用域是函数作用域的子集,实用于 var 的作用域限度同样也实用于 let

反复申明

let 不容许同一个块作用域中呈现 反复申明 。呈现时会导致报错:

function varScope() {
    var name = "var name";
    var name = "var name";
}
function letScope() {
    let name = "let name";
    let name = "let name";    // SyntaxError: Identifier 'name' has already been declared
}

然而,嵌套应用雷同标识符相当于创立一个新的块作用域,因而,雷同的标识符不会报错,这是因为同一个块中没有反复申明:

function letScope() {
    let name = "let name 1";
    if (true) {
        let name = "let name 2";
        console.log(name);    // let name 2
    }
    console.log(name);    // let name 1
}

暂时性死区

var 申明的变量的初始值是 undefined。然而 letvar 不同,通过 let 申明的变量不会在作用域中被晋升。直到申明被执行时才初始化,初始化前拜访变量会导致 ReferenceErrorlet 申明变量之前的执行霎时被称为“暂时性死区”

let 与 var 的另一个重要的区别,就是 let 申明的变量不会在作用域中被晋升。

function deadZone() {console.log(varname);    // undefined
    console.log(letname);    // ReferenceError
    let letname = "let name";
    var varname = "var name";
}

全局申明

var 全局作用域 中申明的变量会成为 window 对象的属性;而 let 申明的变量不会称为 window 对象的属性。

var varname = 'var name';
console.log(window.name); // 'var name'
let letname = "let name";
console.log(window.letname); // undefined

let 申明依然是在全局作用域中产生的,相应变量会在页面的申明周期内存续。因而,为了防止 SyntaxError,必须确保页面不会反复申明同一个变量。

const

const 申明的变量也是块作用域,与 let 基本相同,只是 const 申明变量时必须同时初始化变量。申明的变量的值是只读的,批改 const 申明的变量会导致运行时谬误。

// 申明常量要有一个初始值
const name;    // SyntaxError: Missing initializer in const declaration

// 块作用域
const name = "const name 1";
if (true) {
    const name = "const name 2";
    console.log(name);    // const name 2
}
console.log(name);    // const name 1

name = "const name 2";    // TypeError: Assignment to constant variable.

// 尝试从新申明
const name = "const name 3";    // SyntaxError: Identifier 'name' has already been declared

const 也能够申明对象和数组。当申明的变量是一个对象时,不批改对象援用,而是批改对象外部的属性不违反 const 的限度。

const student = {};
student.name = "小明";

const 本质上保留的并不是变量的值不得改变,而是变量指向的内存地址不得改变。

for 循环中不能应用 const 申明变量,因为迭代时变量会自增就会抛出 TypeError 谬误:

for (const i = 0; i < 10; i++) {}
// TypeError: Assignment to constant variable.

然而,在 for-infor-of 循环中应用不会报错。

for (const key in {name: "小明", age: 24}) {console.log(key);    // name, age
}
for (const value of ["name", "age", "id", "sex"]) {console.log(value);    // name, age, id, sex
}

总结

var 申明变量带来了许多问题,ECMAScript 6 减少的 letconst 对语言更准确地申明作用域和语义提供了更好的反对,晋升了代码品质。新增了两个关键字后,以不再须要 var 来申明变量,这样使得变量有明确的作用域、申明地位,以及不变的值。但申明变量时最好应用 const,这样使得变量在浏览器运行时强制放弃不变。只在提前晓得将来会有批改时,再应用 let

更多内容请关注公众号「 海人为记

退出移动版