首先来看一段代码
a = 2;
var a;
console.log(a);
结果会是什么呢, 2 还是 undefined?
答案是2
再来看一段代码
console.log(a);
var a = 10;
结果又是什么来?
答案是 undefined
首先,JavaScript里代码是由上到下一行一行执行的,这句话不完全正确。
其实引擎在解释JavaScript代码之前首先对其进行编译,编译中会找到变量和函数在内的所有声明,并用合适的作用域将它们关联起来。
举个例子
var a = 1;
这个语句可以分成两个部分
第一部分var a ;
这一句是在编译时阶段进行的
第二部分a = 1;
这一句是按代码顺序执行的
总的来说 一句话 声明提前。(这个过程叫做提升)
声明本身会被提升,而赋值或其它运行逻辑会留在原地。
回头再来看这个代码
a = 2;
var a;
console.log(a);
//根据声明提前 上述代码 等同于
var a;
a = 2;
console.log(a);//结果自然是2
console.log(a);
var a = 10;
//上面代码等同于
var a;
console.log(a);
a = 10;
//因为打印的时候 a 只是声明没有赋值 结果自然是 undefined
好了,既然了解了变量声明提前的道理,再来看下面一段代码
foo();
function foo(){
console.log(a);
var a = 1;
}
根据变量声明提前我们不难看出结果是undefined。
但是,细心的同学会发现:foo 的调用在声明之前。为什么函数在声明之前就可以调用呢?
其实是整个函数都提前了,因为函数里的语句整个就是一个函数声明。之前我错误的以为只有函数名提前了,想的头大。
函数声明会提前,但是,,,函数表达式不会!!废话不多说,看代码
foo();
var foo = function(){
console.log("1");
}
//结果是怎样?报错!为什么?看上面的一句话。
我们知道了变量和函数的声明都会提前,但是他们之间是有优先级的。
函数首先会被提升,然后才是变量。
怎么理解,看如下代码
foo();
var foo;
function foo(){
console.log("1");
}
foo = function(){
console.log("2");
}
//1,2,1,2,1说出你的答案!
既然函数声明的优先级高于变量,那么 把上面代码等价如下
function foo(){
console.log("1");
}
var foo;//相当于重复声明,忽略。
foo(); //结果为1
foo = function(){
console.log("2");
}
关于作用域的问题,相信大家都有一定理解,那么,再来看最后一段代码
foo();
if(true){
function foo(){console.log("1");}
}else{
function foo(){console.log("2");}
}
//在此剧透一下 虽然else内的函数没有执行,但声明仍然会提升。
在这里留给大家据说是一道面试题的题,祝大家做题愉快
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();