换行前端(JS篇2):变量提升机制

119 阅读3分钟

变量提升:

=>当栈内存(作用域)形成,js代码自上而下执行之前,浏览器首先会把所有带var/function关键词进行提前“声明”或者“定义”,这种预先处理机制称之为“变量提升  ”

=>声明(declare):var a (默认值undefined)

=>定义(defined):a=12 (定义其实就是赋值操作)

【变量提升阶段】

=>带var的只声明未定义

=>带function的声明和赋值都完成了

=>变量提升只发生在当前作用域(例如:开始加载页面的时候只对全局作用域下的进行提升,因为此时函数中存储的都是字符串而已)

=>在全局作用域下声明的函数或者变量是”全局变量“,同理,在私有作用域下声明的函数或者变量是”私有变量“【带var/function的才是声明】

=>浏览器很懒,做过的事情不会重复执行第二遍,也就是当代码执行到创建函数这部分代码后,直接的跳过即可(因为在提升阶段就已经完成函数 的赋值操作了)

=>私有作用域形成后,也不是立即执行代码,而是先进行变量提升(变量提升前,先形参赋值)

console.log(a)  //=>undefined

var a=12;

变量提升的一些细节问题

只对等号左边进行变量提升

//=>变量提升: 

var fn:只对等号左边进行变量提升

sum=aaafff111

sum()

fn()//fn is not a function

//=>匿名函数之函数表达式

var fn=function(){

}

//=>普通函数

function sum(){

}

条件判断下的变量提升

在当前作用域下,不管条件是否成立都要进行变量提升

=>带var的还是只声明

=>带function的在老版本浏览器渲染机制下,声明+定义都处理,但是为了迎合ES6中的块级作用域,新版浏览器对于函数**(在条件判断中的函数)**是否成立,都只是先声明,没有定义,类似于var

console.log(a)//=>undefined
if(1===2){
var a=12
}
console.log(a)//=>undefined

变量提升var a 在全局作用域下声明的全局变量也相当于给window设置了window.a=undefinedconsole.log(a)
if('a' in window){
var a=12
}
console.log(a)



f=function () {return true}
g=function () {return false}
~function(){
变量提升:fn g()
if(g()&&[]==![]){
f=function () {return false;}
function g() {return true}
}
}();
console.log(f())
console.log(g())

变量提升机制下重名的处理

1、带var和function关键字声明相同的名字,这种也算是重名了(其实是一个fn,只是存储值得类型不一样)

var fn=12

function fn(){} 

2、关于重名得处理:如果名字重复了,不会重新得声明,但是会重新得定义(重新赋值)【不管是变量提升还是代码执行都是如此】

//变量提升fn()=...{1}
             =....{2}
             =....{3}
             =....{4}fn();//4 
function fn(){console.log(1)}//不执行[变量提升阶段已完成,不重复]
fn();//4
function fn(){console.log(2)}//不执行[变量提升阶段已完成,不重复]
fn();//4
var fn=100;//=>带var得在提升阶段只把声明处理,赋值操作没有处理,所以在代码执行得时候需要完成赋值fn=100
fn();//=>100() 报错:fn is not a function
function fn(){console.log(3)}
fn();
function fn(){console.log(4)}
fn();