前言:
在了解let var const 之前,建议先了解一下ECMAScript也就是所谓的ES标准,我们所有使用的JavaScript脚本语言(JS)与ES都有着密切的关系,那么ES与JS之间到底是什么关系呢,我稍微总结了一下,如下:
ES全称(ECMAScript)是国际标准化组织发布的浏览器脚本语言的标准。
JS(JavaScript)是一种基于对象和事件驱动的具有安全性能的脚本语言。
可以简单的理解为ES是JS语言的国际标准,JS是基于ES的实现。
2011.6 ES5.1版发布并且成为ISO国际标准。
2015.6 ES6正式通过,成为国际标准。
2021.6.22第 121 届 Ecma 国际(Ecma International)大会以远程会议形式召开。正式通过了ES2021标准,ECMAScript 2021 (ES12)成为事实的 ECMAScript 标准。
在ES6出现之前,JavaScript(js)中声明变量有且仅有 var 关键字,函数声明是通过 function 关键字,而在ES6之后,声明变量的方式大有不同分别是 var 、 let 、 const 这三个关键字,函数声明则仍是通过 function。ES6之前ES5中作用域有:全局作用域、函数作用域。没有块作用域的概念。而 ES6后新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。本篇内容主要讨论一下js中变量声明关键字 var 、 let 和 const 之间的区别与作用域。
var let const 的区别与作用域:
总体概括:
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
详细介绍:
1.var
使用var关键字定义的变量,有两种情况,区别是作用域不同。第一种是在函数内使用var声明变量,作用域为函数内,那么这个变量仅限当前函数使用。第二种就是函数外使用var声明变量,作用域为全局,那么这个变量就是全局变量,函数内外均可使用。在声明变量时,如果省略 var ,该变量就会变成默认为全局变量,相当于全局作用域中存在该变量,就会更新其值。
示例:
//定义var类型全局变量
var a = 1;
var a = 1; //可重复定义变量
b = 2;
//var类型测试函数
function varTypeTest() {
c = 3;
var d = 4;
console.log(a); //a = 1;全局变量
console.log(b); //b = 2;默认为全局变量
}
varTypeTest(); //执行varTypeTest函数
console.log(c); //c = 4;默认为全局变量
console.log(d); //d is not defined;因为c为test函数局部变量
2.let
使用let定义的变量,是块级作用域的,不能跨函数、跨块访问。同一作用域中不能重复定义相同的变量名。let非常适合用于 for循环内部的块级作用域。JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响。
示例:
//let类型测试函数
function letTypeTest() {
//let定义局部变量
let a = 1;
let a = 1; //编写报错!!!;不可重复定义变量
let b = 1;
console.log(a); //a = 1;letTypeTest函数局部变量
//修改let定义的局部变量
a++;
console.log(a); //a = 2;
//创建一个块级循环
for (let i = 0; i < 1; i++) {
let b = 2; //仅限于当前块级
b++;
console.log(b); //b = 3;仅限当前块级
}
console.log(b); //b = 1;因为循环内部属于块级作用域;因此不会跨块赋值
}
//跨块(跨函数)测试
function test() {
console.log(a); //a is not defined;因为a为letTypeTest函数局部变量;不可跨块
}
3.const
使用const定义的只能是常量,必须赋初始值,不可以二次赋值,但如果定义的是对象,则可以修改对象属性或者属性值,const也是块级作用域的,不能跨函数、跨块访问。同一作用域中也不能重复定义相同的变量名。
示例:
//const类型常量测试函数
function constTypeTest() {
const a = 1;
const a = 1; //编写报错!!!;不可重重复定义常量
//const定义对象
const obj = {"name": "马冬梅", "age": 22};
//修改const定义的常量
a = 2; //Assignment to constant variable:提示不可以赋值给常量
//修改const定义的对象
obj.age = 25;
obj.sex = "男";
console.log(obj); //{name: '马冬梅', age: 25, sex: '男'};可以修改对象
}
科普知识:变量提升
当 JavaScript 编译所有代码时,所有使用 var 的变量声明都被提升到它们的函数/局部作用域的顶部(如果在函数内部声明的话),或者提升到它们的全局作用域的顶部(如果在函数外部声明的话),而不管实际的声明是在哪里进行的。这就是我们所说的“提升”。请记住,这种“提升”实际上并不发生在你的代码中,而只是一种比喻,与JavaScript编译器如何读取你的代码有关。记住当我们想到“提升”的时候,我们可以想象任何被提升的东西都会被移动到顶部,但是实际上你的代码并不会被修改。
函数声明也会被提升,但是被提升到了最顶端,所以将位于所有变量声明之上。
在编译阶段变量和函数声明会被放入内存中,但是你在代码中编写它们的位置会保持不变。