版权声明:本文为微信公众号前端小二版权所有,如需转载可私信或关注微信公众号留言。 https://blog.csdn.net/qq_34832846/article/details/86487831
《你不知道的JavaScript》第一部分作用域和闭包第3篇。
前两篇主要讲作用域的查询机制和常见形式,本篇要讲的是作用域中的声明提升。
在全局作用域和局部作用域中,都存在声明提升的行为。
所谓声明,包括变量声明和函数声明。而声明提升,就是在作用域范围内,不管内部的变量与函数声明在何处,当执行到这个作用域时,引擎都会首先将当前作用域内的变量和函数声明放置到当前作用域顶端后,再按从上到下顺序执行其他代码。举例:
//1.js
a = 2;
var a;
console.log(a); // 输出=> 2
//2.js
console.log(b); // 输出=> undefined
var b = 2;
经过变量提升后,实际为:
//1.js
var a; //将变量a声明提升到所在作用域顶端
a = 2;
console.log(a); // 2
//2.js
var b; //将变量b声明提升到所在作用域顶端
console.log(b); // undefined
b = 2;
这里注意有个坑了:函数声明有提升行为,函数表达式不会有提升行为。
foo(); // 输出=> 1
function foo(){
console.log(1);
}
fn(); //输出TypeError
bar(); // 输出ReferenceError
var fn = function bar(){
console.log(2);
}
问个问题:为什么fn()
调用会报TypeError
错误呢? 因为此时的fn
值为undefined
,而对undefined
调用方法,就会报TypeError
错误。而使用为函数表达式添加的名称标识符bar
进行方法调用时,输出的则是ReferenceError
另外还有个细节需要注意,在同时有变量声明和函数声明的提升行为中,引擎会执行函数优先的准则。即先提升函数,再提升变量。这再次证明果然js中函数是一等公民的地位。
最后总结下,js中的提升行为,面向的是对象是变量声明和函数声明,排除了包括函数表达式的赋值在内的赋值操作并不会提升。并且函数声明的优先级高于变量声明。
喜欢本文请扫下方二维码,关注微信公众号: 前端小二,查看更多我写的文章哦,多谢支持。