1、变量提升:(创建->初始化)-->赋值-->修改
就是说,以var声明的变量,它的声明会被提升到当前作用域的顶端(注意是变量声明提升,变量的赋值没有提升)
//在if语句中也会提升,跟js的解析顺序有关
<script>
console.log(a);//undefined
var a = 10;
function test(){
console.log(a);//undefined
if(false){
var a =12;
}
console.log(a);//undefined
if(true){
var a =12;
}
console.log(a);//12
}
test();
console.log(a);//10
</script>
2 、那么如果用let和const声明的变量是否会提升?let和const是块级作用域,且存在死区的概念
<script> var a = 10; function test(){ console.log(a);//Cannot access 'a' before initialization let a = 12;//or const a = 12; console.log(a);//12 } test(); console.log(a);//10 </script>
得出结论:let和const,不适用于变量提升;let和const有着'临时性死区'的概念,即从作用域开始到变量申明的这一部分,不能使用该变量,否则会报错。
3 、函数的声明提升:
函数声明方式有三种:
-
函数声明:function test(){};
-
函数表达式:var test = function(){};
其中 函数声明将会被提升:
<script>
test();//输出:函数声明
var test = function(){
console.log("函数表达式");
}
test();//输出:函数表达式
function test(){
console.log("函数声明");
}
test();//输出:函数表达式
</script>
可以看出js中函数不存在重载的概念,后面一个同名函数会覆盖掉前面一个同名函数
4 、函数声明高于变量声明: //函数声明提升比变量声明提升的快,同时会忽略对同名变量的二次申明
<script> console.log(test);/*输出:ƒ test(){console.log("函数申明");}*/ function test(){ console.log("函数申明"); } var test; console.log(test);/*输出:ƒ test(){console.log("函数申明");}*/ var test = 1; console.log(test);//1 </script>
5 、关于let,const的思考
-
const声明的变量如果包含引用类型的调用,是可以修改变量里引用类型指向的数据的
-
let和const声明的全局变量不会被定义成顶层对象的属性
-
let和const不能重复声明一个同名变量,是因为同名变量在栈中的地址问题?
-
js中数据分为基本和引用,存储在栈和堆中,var声明的变量,和let和const声明的在栈和堆中存储的方式是否有什么不同?