变量提升和函数提升及二者优先级

  今早做了一道牛客网上的题目(下图),做的时候就很不确定,做完看到下面的评论就懵了,不知道变量提升和函数提升之间的优先级到底是怎么样的。

 

   查了一下,自己写了几个例子之后就比较明朗了。我的参考链接是这个:JS中变量提升与函数提升及其优先级

  首先是对于提升的原因:JS引擎读取代码时,分为两步,第一步是对整个JS代码的解析读取,第二步是代码的执行。提升发生在第一步,所以在代码执行之前,浏览器的解析器遇到变量名(注意:只能是用var声明的变量,用let或者const声明的变量都不存在提升的问题)和函数声明(注意:JS引擎严格规定句首用 function 的才能算作函数声明,其余的杂牌声明只能算作函数表达式)提升至当前作用域的最前面。

  变量提升(只针对var)的例子:

console.log(a);//undefined
var a = 'hi';
console.log(a);//'hi'

  上述代码在解析后相当于如下:

var a;//只定义不声明就默认是undefined
console.log(a);//undefined
a='hi';
console.log(a);//hi

  函数提升(只针对函数声明)的例子:

console.log(a);    //f a(){console.log('hi');}
console.log(b);    //undefined
function a() {
  console.log('hi');  
}
var b = function() {
  console.log('ok');  
}

  上述代码在变量提升和函数提升之后变成如下:

function a() {
  console.log('hi');  
}
var b;//undefined;
console.log(a);    //f a(){console.log('hi');}
console.log(b);    //undefined
b = function() {
  console.log('ok');  
}

  二者优先级:函数提升会优先于变量提升,而且不会被同名的变量覆盖,但是,如果这个同名变量已经赋值了,那函数变量就会被覆盖。当二者同时存在时,会先指向函数声明。

console.log(a);    //f a() {...}
console.log(a());    //2
var a = 1;
function a() {
  console.log(2);  
}
console.log(a);    //1
a = 3;
console.log(a());    //报错,现在的函数a已经被赋值过后的变量a给覆盖了,无法再调用a()

  上述代码相当于如下:

function a() {
  console.log(2);  
}
var a;
console.log(a);    //f a() {...}
console.log(a());    //2
a = 1;
console.log(a);    //1
a = 3;
console.log(a());    //报错,现在的函数a已经被赋值过后的变量a给覆盖了,无法再调用a()

posted on 2020-08-06 23:12  heySarah  阅读(1244)  评论(0编辑  收藏  举报

导航