在JavaScript中定义变量有两种方式
ES6之前: var 变量名称;
ES6开始: let 变量名称;
区别:
1.通过var定义变量,可以重复定义同名的变量,并且后定义的会覆盖先定义的
var num = 123;
var num = 456;
console.log(num); //456
如果通过let定义变量, "相同作用域内"不可以重复定义同名的变量
let num = 123;
let num = 456; // 报错
2.是否能够先使用后定义
通过var定义变量, 可以先使用后定义(预解析)
console.log(num);
var num = 123;
通过let定义变量, 不可以先使用再定义(不会预解析)
console.log(num); // 报错
let num = 123;
3.是否能被{}限制作用域
无论是var还是let定义在{}外面都是全局变量
var num = 123;
let num = 123;
将var定义的变量放到一个单独的{}里面, 还是一个全局变量
{
var num = 123;
}
console.log(num); //不会报错
将let定义的变量放到一个单独的{}里面, 是一个局部变量
{
let num = 123;
}
console.log(num); //会报错
第三点知识拓展:
1.在JavaScript中{}外面的作用域, 我们称之为全局作用域
2.在JavaScript中函数后面{}中的的作用域, 我们称之为"局部作用域"
3.在ES6中只要{}没有和函数结合在一起, 那么应该"块级作用域"(ES5中没有块级作用域)
{
// 块级作用域
}
if(false){
// 块级作用域
}
while (false){
// 块级作用域
}
for(;;){
// 块级作用域
}
do{
// 块级作用域
}while (false);
switch () {
// 块级作用域
}
function say() {
// 局部作用域
}
4.块级作用域和局部作用域区别
4.1在块级作用域中通过var定义的变量是全局变量
4.2在局部作用域中通过var定义的变量是局部变量
4.3而let只要在{}里面就是局部变量
5.无论是在块级作用域还是在局部作用域, 省略变量前面的let或者var就会变成一个全局变量
== !!!了解即可,开发中千万不能省略let或var!!!==
//块级{}
{
var num = 678; // 全局变量
let num = 678; // 局部变量
num = 678; // 全局变量
}
//函数后的{}
function test() {
var num = 123; // 局部变量
let num = 123; // 局部变量
num = 123; // 全局变量
}
预解析的规则
1.什么是预解析?
浏览器在执行JS代码的时候会分成两部分操作:预解析以及逐行执行代码
也就是说浏览器不会直接执行代码, 而是加工处理之后再执行,
这个加工处理的过程, 我们就称之为预解析
2.预解析规则
2.1将变量声明和函数声明提升到当前作用域最前面**(赋值还是在原来的位置,只是声明提到最前)**
2.2将剩余代码按照书写顺序依次放到后面
3.注意点通过let定义的变量不会被提升(不会被预解析)
// 预解析之前
console.log(num); //undefined
var num = 123;
// 预解析之后
var num;
console.log(num);
num = 123; //赋值还是在原来的位置,只是声明提到最前
// 不会预解析之前
console.log(num); // 报错
let num = 456;
// ES6之前定义函数的格式
console.log(say);
say();
// ES6之前的这种定义函数的格式, 是会被预解析的, 所以可以提前调用
function say() {
console.log("hello it666");
}
// 预解析之后的代码
function say() {
console.log("hello it666");
}
say();
如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
console.log(say);
say(); // say is not a function
// 如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
var say = function() {
console.log("hello itzb");
}
var say; //undefined
say();
say = function() {
console.log("hello itzb");
}