前言
摸鱼时间无聊看了一下,关于变量声明提升与函数声明提升的东西,随手记录一下。
变量提升(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