变量提升
变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”。
alert(a); // undefined var a = 3; alert(a); // 3
相当于:
var a; alert(a); // undefined a = 3; alert(a); // 3
函数声明提升
foo(); // hello function foo () { alert("hello"); }
相当于:
var foo = function () { alert("hello"); }; foo();
函数表达式:
alert(foo); // undefined foo(); // TypeError: foo is not a function var foo = function () { alert("hello"); };
相当于:
var foo; alert(foo); // undefined foo(); // TypeError: foo is not a function foo = function () { alert("hello"); };
变量与函数名相同时
1)函数声明会置顶(置顶成函数表达式)
2)变量声明也会置顶 (函数表达式看成变量形式),(变量与函数置声明顶都是在当前作用域下)
3)函数声明比变量声明更置顶:(函数在变量上面) 变量赋值>函数声明>变量声明
4)变量和赋值语句一起书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置
5)声明过的变量不会重复声明(同一作用域下)
var a = 2;
var a = 3;
JS会默默忽略掉第二个var声明来将程序继续执行下去,而且后面声明的值会覆盖掉前面声明的值
如果重复声明的一个变量有初始值,那么它担当的不过是一个赋值语句的角色.
如果重复声明的一个变量没有初始值,那么它对原来的变量没有任何影响.
最终一切皆为声明变量,然后赋值形式(分解开来分析即可)
var a = 100; function a () { alert(100); } a(); // TypeError: a is not a function
相当于:
var a = function () { alert(1); }; var a = 100; a();
函数内部的变量提升与函数声明提升(提升到当前作用域顶部)
变量提升与函数声明提升不会超过参数
function fn (b) { console.log(b); function b () { console.log(b); } b(); } fn(10);
运行结果:
相当于:
function fn () { var b = function () { console.log(b); }; console.log(b); b(); } fn(10);
一些题目:
1.
var a = 1; function fn () { if (!a) { var a = 2; } alert(a); } fn(); // 2
2.
if (! "a" in window) { var a = 1; } alert(a); // undefined
3.
var a = 1; function fn() { a = 2; return; function a() {} } fn(); alert(a); // 1