随笔 - 118  文章 - 0 评论 - 342 阅读 - 299万
< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

在ES6中,增加了2个声明变量的关键字:let 和 const。在这里将详细介绍let与var的区别、Babel对let的处理以及const的简单使用。

 

1. let

在ES6规范中增加了 let 关键字。let有什么用呢?与var有什么区别呢?

1.1 let 的作用

let,可用于声明一个块级作用域的变量。

如在if()语句内用let声明的变量,不会延伸到if()语句外部。

1
2
3
4
5
6
7
function foo() {
    if (true) {
        let x = 1;
    }
    console.log(x); // error:x is not defined
}
foo();

 

1.2 let与var的区别

在比较两者区别之前,首先需要了解var的作用域和变量提升:

①var没块级作用域。

②使用var在函数或全局内任何地方声明变量相当于在其内部最顶上声明它,这种行为称为Hoisting(提升)。

了解更多var的知识可访问之前的文章:JavaScript var的作用域和提升

 

1) 作用域的区别

var:没有块级作用域,因为变量提升的特性,其声明变量的作用域为整个函数或全局范围。

let:拥有块级作用域的特性,其声明的变量作用域范围从声明处一直到当前块级语句(若存在)的结尾,否则会一直延伸到函数结尾(在函数内)或全局结尾。

 

2) 在全局作用域声明的变量是否作为window对象的成员

var:在全局作用域声明的变量,会作为widnow对象的成员。

let:在全局作用域声明的变量,不会作为window对象的成员。

1
2
3
4
var x = 1;
let y = 1;
console.log(window.x); // => 1
console.log(window.y); // => undefined:let声明的变量没有附加到window对象上

 

3) 同级作用域声明同名变量的区别

在在同一个作用域声明2个名称一样的变量时两者的表现:

var:因变量提升特性,声明2个相同的变量没问题。

let:报错,会提示变量已存在。

1
2
3
4
5
function foo() {
    var x = 1;
    let x = 2; // error:Identifier 'x' has already been declared
}
foo();

 

4) for()循环语句内延迟输出循环变量

在下面代码中使用setTimeout函数延迟输出let和var定义的变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function foo() {
    for (var x = 0; x < 5; x++) {
        setTimeout(function() {
            console.log(x); // => 5 5 5 5 5
        }, 100);
    }
 
    for (let y = 0; y < 5; y++) {
        setTimeout(function() {
            console.log(y); // => 0 1 2 3 4
        }, 100);
    }
}
foo();

可以看到使用var定义的x变量将会输出5次5,而使用let定义的y变量会依次输出0 1 2 3 4,这是为什么呢?

还是因为var的变量提升特性,第一个循环体的变量x,实际就为1个;而第二个循环体,每循环一次创建一次变量y。

所以上面的代码可转换以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function foo() {
    var x;
    for (x = 0; x < 5; x++) {
        setTimeout(function() {
            console.log(x); // => 5 5 5 5 5
        }, 100);
    }
 
    for (let y = 0; y < 5; y++) {
        setTimeout(function() {
            console.log(y); // => 0 1 2 3 4
        }, 100);
    }
}
foo();

 

1.3 Babel对let的处理

let是属于ES6,当使用Babel将其转换为ES5的代码是时是怎么转换的呢?可得出几种转换场景:

1)在同一作用域范围内,若 let 前面没有用 var 定义过的同名变量时,直接使用 var 代替 let 用于声明变量

 

2) 在同一作用域范围内,若 let 前面出现过用 var 定义同名变量时,修改 let 声明的变量名,并用 var 代替声明

 

3) 若在一个循环语句内部,let声明的变量 参与了 延时函数(setTimeout、setInterval)的执行时,那么延时函数会转换一个独立函数

 

2. const

说明:const用于定义一个常量变量。

2.1 特性

①作用域的范围与let一样,声明前无法使用以const声明的常量。

②同一作用域范围内,const不能声明同名常量。

③const声明的常量不会成为window对象的成员。

④当用const声明的常量为值类型(e.g. String、Number)时,修改此常量的值会报错;但当声明的常量为引用类型(e.g. Array、Object)时,只可以修改此常量的成员。

 

2.2 示例

1) 修改值类型的常量会报错

1
2
const x = 1;
x = 2; // => Uncaught TypeError: Assignment to constant variable.

 

2) 修改引用类型的常量的成员不会报错

1
2
3
4
5
6
7
8
9
10
// 1.const声明一个数组
const x = [1, 2, 3];
console.log(x); // => [1, 2, 3]
x[0] = 2; // 修改数组的第一个元素的值
console.log(x); // => [2, 2, 3]
 
// 2.const声明一个对象
const obj = {};
obj.name = 'polk';
console.log(obj.name); // => polk

 

 

3. 扩展阅读

let MDN :https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

const MDN :https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

 

posted on   FangMu  阅读(1044)  评论(0)    收藏  举报
编辑推荐:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
阅读排行:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 管理100个小程序-很难吗
· 基于Blazor实现的运输信息管理系统
· 使用这个工具,基于代码仓库直接生成教程文档,感觉比我自己写的还好
· 如何统计不同电话号码的个数?—位图法
点击右上角即可分享
微信分享提示