简要归纳:
1、分声明和赋值两种情况。声明提升到头部执行,赋值留在原地。
2、变量声明:var a; 变量赋值 : var a=10;
3、函数声明:function a(){}; 函数赋值:var a=function (){};
如果function是声明中的第一个词,那么就是函数声明。否则就是函数表达式。
4、用let进行的声明不会在块作用域中进行提升。
1、JavaScript引擎首先会扫墓所有的变量声明,然后将这些变量声明移动到顶部。而赋值留在原地
eg1:
if (!("a" in window)) {
var a = 1; }
alert(a);
结果:undefined
分析:等价于
var a;
if (!("a" in window)) { //由于a已经被声明。所以判断条件为假。不执行赋值
a = 1; }
alert(a);
结果:undefined
eg2:
var num = 100;
function fn(){
var num = num + 1; //var num=window.num+1;正确(得到alert(101),此时才是外面的全局变量num
return num;
}
alert(fn());
答案是NaN
因为在函数体内部首先把var num提前,这样在赋值的时候 num + 1中的值是undefined,这样进行运算后答案就是NaN,
2、函数声明提升优先级高于变量声明提升。且变量表达式不被提升。
foo();//1
var foo;
function foo(){
console.log(1);
}
foo=function(){ console.log(2);}
处理过程:
functionfoo(){
console.log(1);
}
var foo; //并不执行,重复的声明
foo();
foo=function(){console.log(2);}
注意:如果将foo()调整到最后执行。则结果不同!
var foo;
function foo(){
console.log(1);
}
foo=function(){ console.log(2);}
foo(); //2函数表达式不会被提升
foo(); //TypeError
bar(); //ReferenceError
var foo=function bar(){
//……
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
其处理过程是
var foo;
foo();
bar();
foo=function bar(){
//……
};
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
3、如果function是声明中的第一个词,那么就是函数声明。否则就是函数表达式。
eg1. (function foo() {...} ) 为函数表达式。
eg2. var foo = function () {...} 为函数表达式。
4、用let进行的声明不会在块作用域中进行提升。声明的代码被运行前,声明并不“存在”
{
console.log(bar) //ReferenceError
let bar=2;
}