JavaScript预解析:同名变量和函数、同名函数表达式和同名函数声明,执行哪个和变量提升的坑

先说下预解析的含义,在写js代码调用函数的时候,无论你是在调用位置的前面或者后面声明函数,都可以正常调用,原因是,JavaScript碰到script标签,会将var变量(注意是var)声明和函数声明(注意是声明)提升到当前作用域最前面。

要想搞懂预解析,先记住结论:

变量的提升,指的是声明的提升,赋值(初始化)并不会提升

接下来 就对着这个结论看一些例子:

例1:

console.log(num); //undefined
    var num = 2;

变量声明提升,赋值不提升,所以上述代码相当于:

var num;
console.log(num);
num = 2;

例2:

var num = 2;
var num;
console.log(num); //2

是不是以为是undefined呢?千万别忘了变量是会提升的,看下面代码就明白为什么是2了:

var num;
var num;
num = 2;
console.log(num);

这里有个问题,看下面代码:

function f() {}
var f
console.log(f); //function f() {}

 按理说,这里应该是undefined,结果明显不是,这里个人以为可以理解成,变量的声明提升后会在函数前面

再将代码作如下修改:

function f() {
console.log(num); // undefined
}
var num

这里函数里面能访问到num,证明变量的声明会在函数声明之前

这个问题是个人的理解,有疑问的读者也可以去查些资料。 


例3:

var f = function() {
   console.log(1)
}
function f() {
  console.log(2)
}
f(); // 1

这个例子结果是1的原因,可以看下面的代码:

var f;
function f() {
   console.log(2)
}
f = function() {
  console.log(1)
}
f();

例4:

f(); // 2
var f = function() {
  console.log(1)
}
function f() {
  console.log(2)
}

这个例子和前一个只是函数调用位置发生了改变,结果也变了,可以尝试自己按照步骤一步步重新写在纸上,结果如下:

var f;
function f() {
  console.log(2)
}
f();
f = function() {
  console.log(1)
}

例5:

f(); //报错
var f = function(){
   console.log('k')
}

这个例子应该很简单,只是将例1中的变量换成了函数:

var f;
f();
f = function(){
  console.log('k')
}

调用一个未赋值的函数,当然会报错,注意一下,这个例子,将函数表达式换成函数声明就不会报错了,因为函数声明会提升,这也是我们常用函数声明的一个原因,可以在任何位置调用。


例6:

var num = 2;
function f() {
  num = 1;
  console.log(num); //1
  return
  var num = 3;
}
f();
console.log(num) //2

return后面的语句虽然不会执行,但是变量还是会提升:

var num = 2;
function f() {
   var num
   num = 1;
   console.log(num); //1
   return
   num = 3;
}
f();
console.log(num) //2

例7:

console.log(num);// 报错
num = 2;

我们开篇就说过,只有var会提升,隐式全局变量并不会提升,所以结果和例1不同,并不是undefined


猜你喜欢

转载自blog.csdn.net/m0_37897013/article/details/81701016