js提升机制(hoisting)

转自:http://www.cnblogs.com/fcaa/p/5948438.html

从网上看到这么一段代码:

 var c = 2;

 function c(){

  c = 22;

  console.log("c="+c);

 }

 c();//会报错,变量提升机制导致的(c is not a function)

问运行结果是什么,然后不假思索的就以为是22,因为c=22这行看起来就是对外面的全局变量c重新定义了

但是实际上不是的,这句话不会执行到c()的时候会报错(number is not a function),有点蒙蔽,这是怎么了,查了好久,才知道js有个提升机制,变量和函数(函数声明的方式有提升机制,函数表达式没有这个机制)都有提升机制,而且函数提升机制的优先级高于变量的,这也就是说当函数名和变量名相同的时候,拿上面这个例子来说,c被提升到代码最前端,并且被赋值为一个函数,然后才会 被赋值为2,上面的代码等效于下面这个:

var c = function c(){

  c = 22;

  console.log("c="+c);

};

c = 2;

c();

执行的时候,c先被赋值为一个函数,然后紧接着又被赋值为数字2,这样在这句赋值语句下面执行c()的时候,c就不是函数了,而是数字,如果在c = 2;这句话的上面执行c()的话,就没有问题了,结果是c = 22;

再来看另一个问题,函数声明和函数表达式有什么不同,就是下面这两种情况:

d();//1

function d(){//方式1

  alert("1");

}

d();//undefined is not a function

var d = function(){//方式2

  alert("1");

};

这两种声明函数方式不同之一在于:

方式1可以在d声明之前使用d()来调用函数,方式2却不可以

这个也是可以用变量提升机制来解释的,方式1的写法和下面这个等价:

var d = function d(){

  alert("1");

};

d();

所以执行没有问题,但是第二种写法的函数就没有变量提升机制,好像也可以用这个方式来解释,第二种写法等价于下面这样:

var d;

d();

d = function(){

  alert("1")

};

这样的话,执行d()的时候,d还没有被定义为函数,只是被声明了,所以会执行报错。(这样应该可以解释的通,不对的地方,请务必让我知道)

来看个复杂点的例子:

var a = 1;

function b() {        //变量提升机制:如这个例子所示,执行b()时

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

  a = 10; //这可不是对外面的全局变量a定义哦

  console.log(a); //10(局部变量)

  var a = 11;

  console.log(a); //11(局部变量)

  return;

  function a(){

    alert("abc");

  }

}

b();

console.log(a); //1(全局变量) 

上面的例子等价于下面这样:

var b = function b(){

  var a = function a(){

    alert("abc");

  }

  console.log(a);

  a = 10;

  console.log(a);

  a = 11;

  console.log(a);

  return;

}

var a;

a = 1;

b();

console.log(a);

原文地址:https://www.cnblogs.com/allenda/p/6083101.html