乐趣区

关于javascript:变量声明提升和函数声明提升

  • 变量申明晋升和函数申明晋升就是将申明的变量或者函数,晋升至所在作用域的顶部。

平时咱们都认为 JavaScript 代码是由上向下执行的,然而也有非凡状况,这个状况就会扭转,晋升就属于非凡的状况。

  // 看以下示例代码:a=2;
  var a;
  console.log(a)//2

后果不是报错,而是 2。
咱们常见的定义形式是 var a = 2
其实这是两个申明。var a 是定义申明,a= 2 是赋值申明。定义申明先在编译期进行,赋值申明留在原地期待执行。所以以上代码中,var a 是会先被进行的。 输入的后果为 2。

// 看以下示例代码
console.log(a)//undefined
var a;
a=2;

只有 a 在赋值前被输入的话,就会输入 undefined(不是报错)。
这种状况下很多人认为会抛出ReferenceError: a is not defined

下面咱们说过定义申明 var a 是在编译期进行的,就如 var a 的地位被挪动到了顶部,这个行为就是 晋升

所以这段代码的真正执行程序应该是:

var a;
console.log(a)//undefined
a=2;

只有申明自身会被晋升,其余的运行逻辑不变。

要留神的是变量的晋升只晋升至所在作用域的顶部。

在函数中同理,函数领有本人的作用域,所以函数中的变量晋升,也是晋升到这个作用域的顶部,例如:

test();
function test(){console.log(a)//undefine
    var a =2
}

实在的执行程序是:

function test(){
    var a;
    console.log(a)//undefine
    a =2
}
test();

如果是所在作用域的内部输入变量,后果依然是报错(ReferenceError: a is not defined)
函数申明也被晋升了并且调用,所以函数内的代码也执行,并不会报错。

咱们再看一下函数表达式:

test();//TypeError
a();//ReferenceError
var test= function a(){//...}

如上,函数表达式并不会被晋升!
这段代码的真实情况能够这样了解:

var test;
test();//TypeError
a();//ReferenceError

var test= function a(){//...}
  • 变量申明和函数申明的优先级

    • 函数申明的优先级 > 变量申明
test()//1
var test;
function test(){console.log(1)
}
test= function a(){console.log(2)
}

这段代码被引擎解析的实在程序:

function test(){console.log(1)
};
test();//1
var test;
test= function a(){console.log(2)
}

只会输入 1。

如果遇到函数反复定义:

test();//2
function test(){console.log(1)
};
function test(){console.log(2)
};

前面申明的函数会笼罩之前的。

如果是在块内申明函数:

test()//TypeError:test is not a function
var a=true;
if(a){function test(){console.log(true)
    }
}else{function test(){console.log(false)
        }
}

为什么会有这样的状况?因为块也会造成一个作用域,所以要防止如此应用。

退出移动版