JavaScript let 和 const
ECMAScript 2015
ES2015 新加添了两个很重要的 JavaScript 关键字: let 和 const。
const 声明是一个只读的常量,并且声明后,常量的值就不可改动。
var 作为唯一的声明变量关键字,本篇将着重介绍var的作用域和变量提升
在ES6 出现之前,JavaScript 中声明变量就只有通过 var 关键字,函数声明是通过 function 关键字,而在ES6之后,声明的方式有 var 、 let 、 const 、 function 、 class ,本文主要讨论 var 、 let 和 const 之间的区别。
一、全局与变量
在函数外声明的变量作用域是全局的:
示例代码
var carName = "Volvo";
// 可使用 carName 变量
function myFunction() {
// 也可使用 carName 变量
}
演示一下
全局变量可在 JavaScript 程序中任何位置都可访问。
二、局部与变量
函数内声明的变量作用域是局部:
示例代码
// 不可使用 carName 变量
function myFunction() {
var carName = "Volvo";
// 这可使用 carName 变量
}
// 不能使用 carName 变量
声明的变量只能在函数内容访问。
三、JavaScript 块级作用域
var 关键词声明的变量不能块作用域。在块 {} 内声明变量可从块外进行访问。
{ var x =2;}// 这里能够运用 x 的变量
JavaScript 没有块作用域,是在 ES2015 之前。
能够运用 let 关键词声明具有块作用域的变量。
在块 {} 内声明的变量不开从外访问。
{ let x =2;}// 这里不可使用 x 的变量
四、重新定义变量
使用 var 关键字重新声明变量能够带来问题。
在块中重新声明变量也能重新声明块外的变量:
示例代码
var x = 10;
// 输出为 x 为 10
{
var x = 2;
// 输出为 x 为 2
}
// 输出为 x 为 2
演示一下
let 的关键字 就可重新声明变量解决这个问题。
示例代码
var x = 12;
// 输出为 x 为 12
{
let x = 2;
// 输出为 x 为 2
}
// 输出为 x 为 12
演示一下
五、浏览器的支持
Internet Explorer 11 之前老版本的浏览器 是不支持 let 关键词。
下面列表出了一个完全支持 let 关键词的浏览器版本 和版本号:
| | | | |
---|
Chrome 49 | IE / Edge 12 | Firefox 44 | Safari 11 | Opera 36 |
Mar, 2016 | Jul, 2015 | Jan, 2015 | Sep, 2017 | Mar, 2016 |
六、循环作用域
var 关键字的循环:
示例代码
var i = 6;
for (var i = 0; i < 12; i++) {
// 部分源代码..
}
// 输出为 i 为 12
演示一下
let 关键字的循环:
示例代码
let i = 6;
for (let i = 0; i < 12; i++) {
// 部分源代码..
}
// 这里输出 i 为 6
演示一下
在第一个示例代码中,var 重新声明了循环之外的变量。
在第二个示例代码中,let 并没有重新声明循环外的变量。
七、局部变量
声明变量时函数内,使用 var 和 let 很类似。。
都有函数作用域 局部
// 以用 var
function myFunction() {
var carName = "hai"; // 局部函数作用域
}
// 以用 let
function myFunction() {
let carName = "hai"; // 局部函数作用域
}
八、全局 作用域
在块外使用声明,那么 var 和 let 很相似。
全局的作用域他们都有:
// 以用 var
var x = 12; // 全局作用域
// 以用 let
let x = 6; // 全局作用域
九、HTML 全局变量
JavaScript 情况下,全局作用域是指向 JavaScript 环境。
在 HTML 中,全局作用域是指向 window 对象。
运用 var 关键词声明定义的全局变量属 window 对象:
示例代码
var carName = "hai";
// 这里可使用 window.carName
演示一下
运用 var 关键词声明定义的全局变量属 window 对象:
示例代码
let carName = "hai";
// 这里不可使用 window.carName
演示一下
十、重新变量
var 关键字声明 变量允许在任何位置使用:
示例代码
var x = 4;
//现为 x 为 4
var x = 6;
// 现为 x 为 6
演示一下
同样的作用域或者块级作用域中,变量不允许使用 let 关键字来重新 var 声明变量:
var x =2;// 合法 let x =3;// 不合法 {var x =4;// 合法 let x =5// 不合法}
同样的作用域或者块级作用域中,变量不允许使用 let 关键字来重新 let 声明变量:
let x =2;// 合法let x =3;// 不合法{let x =4;// 合法let x =5;// 不合法}
同样的作用域或者块级作用域中,变量不允许使用 var 关键字来重新 let 声明变量:
let x =2;// 合法var x =3;// 不合法{let x =4;// 合法var x =5;// 不合法}
不同作用域或块中,let 重新声明变量是可以的:
let x =2;// 合法{let x =3;// 合法}{let x =4;// 合法}
1
一、1提升变量
使用 var 在函数或全局内任何地方声明变量相当于在其内部最顶上声明它,这种行为称为Hoisting(提升)。
示例代码
// 在这能够运用 carName 来变量
var carName;
演示一下
let 关键字定义的变量需要先声明在使用。
// 本处你不可使用 carName
let carName;
十二、const 关键字
我们都知道使用const关键字限定一个变量为只读,但它是真正意义上的只读吗?实际中又该如何使用const关键字?在解答这些问题之前,我们需要先理解const关键字的基本使用。本文说明C中的const关键字,不包括C++。
十三、基本介绍
const是constant的简写,是不变的意思。但并不是说它修饰常量,而是说它限定一个变量为只读。
修饰普通变量
例如:
const int NUM = 10;
由于使用了const修饰NUM,使得NUM为只读,因此尝试对NUM再次赋值的操作是非法的,编译器将会报错。正因如此,如果需要使用const修饰一个变量,那么它只能在开始声明时就赋值,否则后面就没有机会了(后面会讲到一个特殊情况)。
修饰数组
例如使用const关键字修饰数组,使其元素不允许被改变:
const int arr[] = {0,0,2,3,4};
试图修改arr的内容的操作是非法的,编译器将会报错:
error: assignment of read-only location ‘arr[2]’
修饰指针
修饰指针的情况比较多,主要有以下几种情况:
1.const 修饰 *p,指向的对象只读,指针的指向可变:
int a = 9;
int b = 10;
const int *p = &a;
这里为了便于理解,可认为const修饰的是*p,通常使用*对指针进行解引用来访问对象,因而,该对象是只读的。
2.const修饰p,指向的对象可变,指针的指向不可变:
int a = 9;
int b = 10;
int * const p = &a;
3.指针不可改变指向,指向的内容也不可变
int a = 9;
int b = 10;
const int * const p = &a;
看完上面几种情况之后是否会觉得混乱,并且难以记忆呢?我们使用一句话总结:
const放在*的左侧任意位置,限定了该指针指向的对象是只读的;const放在*的右侧,限定了指针本身是只读的,即不可变的。
如果还不是很好理解,我们可以这样来看,去掉类型说明符,查看const修饰的内容,上面三种情况去掉类型说明符int之后,如下:
const *p;
const右边修饰谁,就说明谁是不可变的。上面的说法仅仅是帮助理解和记忆。借助上面这种理解,就会发现以下几种等价情况:
const int NUM = 10;