代码改变世界

声明提升

2016-04-20 18:01  孤独大兔子  阅读(235)  评论(0编辑  收藏  举报

之前理解有一些错误,今天补过一下....

我们都知道 常用的函数写法有两种,一种是普通的函数声明,一种是使用变量初始化函数,他们两个最大的区别就是如果用变量初始化函数的声明方式,如果在声明前调用函数,是没有办法调用到的。

 为什么会报 not a function(...)的错,我们都知道如果没有声明肯定会报not defined,如果声明了没有赋值会报undefined,一个非函数的变量在执行的时候用()执行,才会报not a function.

说明也许是()的过,那么去掉()呢

刚好印证了上面所说的,如果声明了没有赋值会报undefined,那么说明函数声明了,但没有赋值而已(把声明提前了),JavaScript中的变量提升时函数表达式中只会提升名称,函数体只有在执行到赋值语句时才会被赋值:

如果一个函数是这样写的

(function(){ 
    var a='One'; 
    var b='Two'; 
    var c='Three'; 
})() 

在执行时声明提前了,变成了这样

(function(){ 
    var a,b,c; 
    a='One'; 
    b='Two'; 
    c='Three'; 
})() 

进一步证明

例1:

var v='Hello World'; 
alert(v);     //Hello World

var v='Hello World'; 
(function(){ 
alert(v); 
})()           //Hello World

var v='Hello World'; 
(function(){ 
alert(v); 
var v='I love you'; 
})()           //undefined

最后一个弹出undefined,因为声明提前了最后一个函数在执行时变成了

var v='Hello World'; 
(function(){ 
  var v;
  alert(v); 
  v='I love you'; 
})() 

刚好符合之前说的,声明了但没有赋值,所以会弹出undefined

自我感觉特别绕的面试题例2:

var foo = 1; 
function bar() { 
  if (!foo) { 
   var foo = 10; 
  } 
  alert(foo); 
} 
bar();     //10

一定感觉很奇怪,为什是10,其实如果把前面的var foo = 1; 去掉,也是10,说明是不是10和前面的全局变量没有关系,我们循序渐进

function bar() { 
  if (true) { 
   var foo = 10; 
  } 
  alert(foo); 
} 
bar()     //10

///////////////////////////////////////

function bar() { 
  if (false) { 
   var foo = 10; 
  } 
  alert(foo); 
} 
bar()     //undefined

说明在判断的时候,是true才能赋值,其实这里是提升了声明,变成了这样

var foo = 1; 
function bar() { 
  var foo;
  if (!foo) { 
    foo = 10; 
  } 
  alert(foo); 
} 
bar();

回到最初所说的,只声明未赋值,弹出undefined,那么直接输出foo,肯定是undefined,!undefined得到true,so...就得到了我们看到的结果

 

补充两道题

var a=1;
function test(){
   var a=3;
   return;
}
test()
a      //1
var a=1;
function test(){
  a=3;
  return;
}
test()
a    //3
var a = 1; 
function b() { 
  a = 10; 
  return; 
  function a() {} 
   } 
  b(); 
alert(a);         //1

 第一个是因为局部变量,所以无论是几,都会是打印的全局变量

第二个是执行后就变成了全局变量

第三个是变量提升,先是var a,所以a变成了局部变量