声明提升

变量声明提升:

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

console.log(b);
var b = 3;

 直觉上会认为第一次输出a的值为undefined,第二次输出b的值为3,但是真正的答案是2和undefined,是因为代码发生了如下变化

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

var b;
console.log(b);
b = 3;

定义变量会把变量提升到最前面,但是赋值过程会被留在原地等待引擎在执行阶段执行

知道了变量提升,现在来看看下面一段代码

console.log(a);
var a = 0;
function fn(){
  console.log(b);
  var b = 1;
  function test(){
    console.log(c);
    var c = 2;
  }
  test();
}
fn();
//变量提升后,代码如下
var a;
console.log(a);  //undefined
a = 0;
function fn(){
  var b;
  console.log(b);  //undefined
  b = 1;
  function test(){
    var c;
    console.log(c);  //undefined
    c = 2;
  }
  test();
}
fn();

函数提升:

 有函数声明和函数表达式两个概念,要对这两个进行区分

  首先是函数声明

foo();
function f00(){
console.log(1);
}

 上面的代码能输出1,就是因为foo()函数声明进行了提升,如下:

function foo(){
  console.log(1);
}
f00();

然后是函数表达式,先看看函数表达式长什么样子

var demo = function fn1(){
     //代码块
}
 demo(); //正确的调用
 fn1();  //错误的调用

//前后两个函数的名字可以相同,也可以不相同
//function后面的这个名字可以省略,并且只能在函数内部使用

函数声明会提升,但是函数表达式却不会

foo();
var foo = function(){
  console.log(1); //报错 foo is not a function
}

 变量标识符foo被提升分配给全局作用域,但是foo没有赋值,foo()对undefined值进行函数调用而导致非法操作,所以会抛出异常

可以看出,函数声明由于有函数提升,所以可以在任意位置调用,但是函数表达式没有函数提升,所以只能在函数表达式之后调用

test1(); //100
demo1(); //demo1 is not a function
function test1(){
  console.log(100);
}
var demo1 = function test2(){
  console.log(50);
}

变量声明和函数声明都会被提升,但是函数声明会覆盖变量声明

var a ;
function a(){}
console.log(a);  //function a(){}

但是如果变量存在赋值操作,最终的值为变量的值

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

 

原文地址:https://www.cnblogs.com/jrrrrr/p/9242736.html