深刻理解变量声明提高和函数声明提高

变量声明提高

转载:http://blog.csdn.net/qq673318522/article/details/50810650函数

一、变量定义

能够使用var定义变量,变量若是没有赋值,那变量的初始值为undefinedspa

二、变量做用域

变量做用域指变量起做用的范围。变量分为全局变量和局部变量。全局变量在全局都拥有定义;而局部变量只能在函数内有效。 
在函数体内,同名的局部变量或者参数的优先级会高于全局变量。也就是说,若是函数内存在和全局变量同名的局部变量或者参数,那么全局变量将会被局部变量覆盖。 
全部不使用var定义的变量都视为全局变量.net

三、函数做用域和声明提早

JavaScript的函数做用是指在函数内声明的全部变量在函数体内始终是有定义的,也就是说变量在声明以前已经可用,全部这特性称为声明提早(hoisting),即JavaScript函数里的全部声明(只是声明,但不涉及赋值)都被提早到函数体的顶部,而变量赋值操做留在原来的位置。以下面例子: 
注释:声明提早是在JavaScript引擎的预编译时进行,是在代码开始运行以前。code

var scope = 'global';
function f(){
    console.log(scope);
    var scope = 'local';
    console.log(scope);
}

因为函数内声明提高,因此上面的代码其实是这样的 blog

var scope = 'global';
function f(){
    var scope;    //变量声明提高到函数顶部
    console.log(scope);
    scope = 'local';    //变量初始化依然保留在原来的位置
    console.log(scope);
}

 通过这样变形以后,答案就就很是明显了。因为scope在第一个console.log(scope)语句以前就已经定义了,可是并无赋值,所以此时scope的指是undefined.第二个console.log(scope)语句以前,scope已经完成赋值为’local’,因此输出的结果是localip

函数声明提高

一、函数的两种建立方式

  • 函数声明
  • 函数表达式

函数声明语法内存

f('superman');
function f(name){
    console.log(name);
}

运行上面的程序,控制台能打印出supemran。 
函数表达式语法作用域

f('superman');
var f= function(name){
    console.log(name);
}

运行上面的代码,会报错Uncaught ReferenceError: f is not defined(…),错误信息显示说f没有被定义。 
为何一样的代码,函数声明和函数表达式存在着差别呢? 
这是由于,函数声明有一个很是重要的特征:函数声明提高,函数声明语句将会被提高到外部脚本或者外部函数做用域的顶部(是否是跟变量提高很是相似)。正是由于这个特征,因此能够把函数声明放在调用它的语句后面。以下面例子,最终的输出结果应该是什么?:get

var getName = function(){
    console.log(2);
}
function getName (){
    console.log(1);
}
getName();

可能会有人以为最后输出的结果是1。让咱们来分析一下,这个例子涉及到了变量声明提高函数声明提高。正如前面说到的函数声明提高,函数声明function getName(){}的声明会被提早到顶部。而函数表达式var getName = function(){}则表现出变量声明提高。所以在这种状况下,getName也是一个变量,所以这个变量的声明也将提高到底部,而变量的赋值依然保留在原来的位置。所以上面的函数能够转换成下面的样子:io

function getName(){    //函数声明提高到顶部
    console.log(1);
}
var getName;    //变量声明提高
getName = function(){    //变量赋值依然保留在原来的位置
    console.log(2);
}
getName();    // 最终输出:2

因此最终的输出结果是:2。在原来的例子中,函数声明虽然是在函数表达式后面,但因为函数声明提高到顶部,所以后面getName又被函数表达式的赋值操做给覆盖了,因此输出2

相关文章
相关标签/搜索