之前理解有一些错误,今天补过一下....
我们都知道 常用的函数写法有两种,一种是普通的函数声明,一种是使用变量初始化函数,他们两个最大的区别就是如果用变量初始化函数的声明方式,如果在声明前调用函数,是没有办法调用到的。
为什么会报 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变成了局部变量