自己关于变量声明提升的理解(一)

308 阅读2分钟

前言

摸鱼时间无聊看了一下,关于变量声明提升与函数声明提升的东西,随手记录一下。

变量提升(Hoisting)被认为是, Javascript中执行上下文 (特别是创建和执行阶段)工作方式的一种认识。在 ECMAScript® 2015 Language Specification 之前的JavaScript文档中找不到变量提升(Hoisting)这个词。不过,需要注意的是,开始时,这个概念可能比较难理解,甚至恼人。 例如,从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在预编译阶段被放入内存中。

因此,严格来说应该叫声明提升

作用域

JavaScript 没有块级作用域经常会导致理解上的困惑。在其他类 C 的语言中,由花括号封闭的代码 块都有自己的作用域(如果用 ECMAScript 的话来讲,就是它们自己的执行环境),因而支持根据条件来 定义变量。 ----《JavaScript高级程序设计第3版》

  • 全局作用域 (整个代码块)
  • 局部作用域(函数作用域)
  • es6中的块级作用域(let、const)

注意点: if是没有作用域的

console.log(a)  //undefined
if(true){
  var a = 1;
}
console.log(a)  // 1
//相当于
var  a ;
console.log(a)  //undefined
if(true){
   a = 1;
}
console.log(a)  // 1

变量声明提升

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

函数声明提升

在此之前我们需要了解一下函数主要有哪些写法?如何区分?
区分函数声明和表达式最简单的方法是看function 关键字出现在声明中的位置(不仅仅是一行代码,而是整个声明中的位置)。如果function 是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。

console.log(f1) // f1方法
f1();  // a
var f1 = "变量f1";
console.log(f1) // 变量f1

f2();  //f2 is not a function
f3();  //f3 is not a function 

//函数声明
function f1(){
   console.log("a")
}
//匿名函数表达式
var f2 = function(){
   console.log("b")
}
//具名函数表达式
var f3 = function f33(){
   console.log("c")
}

因此,函数的提升也要注意点,同时也发现函数声明提升比变量声明提升更优先

实题解析

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

相当于

function a(){
  var f;
  if(!f){
     f = 2;  
  }
  console.log(f) 
}
var f;
f = 1;
a();  //2
好了,这便是我对此的暂时理解。如若有误,希望指出,多谢!