接着上一篇讲<JavaScript Scoping & Hoisting>javascript
Javascript是一门容易遭人误解的语言,可是它的强大毋庸置疑。我的以为,要想深刻理解Javascript语言,首先必须对其基本的概念(例如:Scope,Closure,Hoisting等)要真正理解。今天想经过本身的理解来对Javascript Hoisting(国内通常翻译为 变量提高)作一个阐述:java
在解释Javascript Hoisting以前,先看一下几段代码:函数
//代码段1-------------------------- var myvar = '变量值'; console.log(myvar); // 变量值 //代码段2-------------------------- var myvar = '变量值'; (function() { console.log(myvar); //变量值 })(); //代码段3---------------------------- var myvar = '变量值'; (function() { console.log(myvar); // undefined var myvar = '内部变量值'; })();
代码段1会在控制台打印出 变量值 ,很容易理解;代码段2也会在控制台打印出 变量值 ,Javascript编译器首先在匿名函数内部做用域(Scope)查看变量myvar是否声明,发现没有,就继续向上一级的做用域(Scope)查看是否声明 myvar,发现存在,即打印出该做用域的myvar值。但代码段3只是对代码段2作一个微调,结果却输出了undefine!!!测试
在理解代码段3以前,必须先理解Javascript Hoisting的概念。Javascript Hoisting:In javascript, every variable declaration is hoisted to the top of its declaration context.个人理解就是在Javascript语言中,变量的声明(注意不包含变量初始化)会被提高(置顶)到声明所在的上下文,也就是说,在变量的做用域内,无论变量在何处声明,都会被提高到做用域的顶部,可是变量初始化的顺序不变。.net
下图的左边和右边的代码输出结构是同样的,左边的代码段在JS执行时,实际的执行顺序如右边的代码所示(JS编译器会将变量声明进行提高处理)。翻译
理解了提高的概念以后,再回到开头的代码段3的理解中来,代码段3和在被Hositing以后的代码以下图所示:code
两者输出的结构都为undefined!可理解为内部变量myvar在匿名函数的内最后一行进行变量声明并赋值,可是JS解释器会将变量声明(不包含赋值)提高(Hositing)到匿名函数的第一行(顶部),因为只是声明myvar变量,在执行console.log(myvar)语句时,并未对myvar进行赋值,因此JS输出undefined。blog
若是变量声明未提高(Hositing)置顶,则应该会报错误。以下图所示:ip
下面给个测试题,来看看你对Hositing的概念是否理解作用域
//测试代码---------------------- var myvar = '变量值'; (function() { console.log(myvar); // ? myvar = '内部变量值'; })();
该代码段应该输出什么值呢?