变量提升:当栈内存(作用域)形成,JS代码自上而下执行之前浏览器首先会把所有带“VAR / FUNCTION”
关键字的进行前的 “声明”和“定义”这种预先处理机制称之为“变量提升”。
变量声明(declare):var a =12;function sum(){};
使用变量步骤:a.声明–>b.赋值–>3.调用
<script type="text/javascript">
var a; //声明
a=10; //赋值
console.log(a); //输出10 调用;
function sum(){ //声明赋值
console.log(0)
}
sum(); //输出0 调用
</script>
【变量提升阶段】
1、带“VAR”的是只声明未定义
2、带“FUNCTION”的声明和赋值都完成
3、变量提升只发生在当前作用域(例如:开始加载页面的时候只对全局作用域下的进行提升 ,因为此时函数中储存的都是字符串而已)
4、全局作用域下声明的函数或者变量是“全局变量”同理,在私有作用域下声明的变量是“私有变量”。
【带VAR 和FUNCTION 的才是声明】
浏览器做过的事情不会重复第二遍,也就是,当代码执行遇到创建函数这部分代码后,直接的跳过即可(因为在提升阶段就已经完成函数的赋值操作了)
带var和不带var的区别
在全局作用域下声明一个变量,也相当于给window全局对象设置了一个属性,变量的值就是属性值(私有作用域中声明的私有变量和window没啥关系)
在变量提升阶段,在全局作用域中声明了一个变量A,此时就已经把A当做属性赋值给window了只不过此时还没有给A赋值,默认值undefined, in检测某个属性是否属于这个对象。
例如:
<script>
console.log(a,b) //=>输出 undefind undefeind
var a=12,
b=12;
function fn(){
console.log(a,b) //=> 输出 undefind 12
var a=b=13;
// 执行过程相当于 var a=13 ; b=13
console.log(a,b) //=》输出 13 13
}
fn();
console.log(a,b) //=> 输出12 13
</script>
私有作用域带var和不带var也有区别
1、带var的私有作用域变量提升阶段,都声明为私有变量,和外界没有任何关系。
2、不带var不是私有变量,会向它的上级作用域查找,看是否为上级的变量,不是继续向上查找,一直找到window为止(我们把这种查找机制叫做:作用域链),也就是我们在私有作用域中操作的这个非私有变量,一直是别人的变量。