首先把所有的声明提前,并且函数声明在变量声明之前,然后再赋值操作
注:提升是提升到其所在作用域的最顶端,不是提升到全局的最顶端
console.log(global); // undefined
var global = 'global';
console.log(global); // global
function fn () {
console.log(a); // undefined
var a = 'aaa';
console.log(a); // aaa
}
fn();
为什么一开始打印global 会是undefined呢?
其实代码是按下面的顺序执行的
var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值
console.log(global); // undefined
global = 'global'; // 此时才赋值
console.log(global); // 打印出global
function fn () {
var a; // 变量提升,函数作用域范围内
console.log(a);
a = 'aaa';
console.log(a);
}
fn();
如果函数声明和变量声明使用的是同一个变量名称,函数声明的优先级高于变量声明的优先级
例如
foo(); //输出1
var foo = function(){
console.log(2)
}
function foo(){
console.log(1)
}
它的执行顺序为:
function foo(){
console.log(1)
}
var foo;
foo(); //输出1
foo = function(){console.log(2)}
自执行函数
var foo='hello';
(function(foo){
console.log(foo);
var foo=foo||'world';
console.log(foo);
})();
console.log(foo);
执行如下:
var foo = 'hello';
(function () {
var foo;
console.log(foo);//undefined
foo = foo || 'world';
console.log(foo);//world
})();
console.log(foo);//hello
函数表达式的声明提升
函数提升优先级比变量提升优先级要高,且不会被变量声明覆盖,但是会被变量赋值覆盖
var getName = function (){
console.log(2)
}
function getName(){
console.log(1)
}
getName()
执行如下:
function getName(){
console.log(1)
}
var getName;
getName = function (){
console.log(2)
}
getName() // 2
关于函数形参相关的提升,如果有形参传入,那么形参赋值是在变量提升之前
function fun(a){
console.log(a);
var a=2
}
fun(1)
执行如下:
function fun(a){
var a= 1; //形参传入并赋值
var a; //内部变量提升
console.log(a); //1
a=2
}
fun(1)
还有一道老问题也是这个道理
var foo='hello';
(function(foo){
console.log(foo);
var foo=foo||'world';
console.log(foo);
})(foo);
console.log(foo);
执行如下:
var foo='hello';
(function(foo){
var foo = 'hello'; //形参传入并赋值
var foo; //内部变量提升
console.log(foo); //'hello'
foo=foo||'world';
console.log(foo); // 'hello'
})(foo);
console.log(foo); //'hello'