JavaScript 中变量以及函数的提升, 在我们平时的项目中其实还是挺常用的, 尤其是大型项目中, 不知不觉就会顺手添加一些变量, 而有时候自己的不小心就会酿成一些不必要错误, 趁有时间整理一下自己对于 JS 中变量及函数提升的理解.
首先, 看一个题目:
- console.log(a); // undefined
- var a = 1;
- console.log(a); // 1
- console.log(b());
- function b(){return 2;} // 2
- console.log(c) // 报错
- let c = 4;
- console.log(d()) // 报错
- var d = function(){return 3;} // 报错
- (function(){
- var m = n = 1;
- })()
- console.log(m) // 报错
- console.log(n) // 1
上面的实例对于 JavaScript 变量及函数提升的可谓是淋漓尽致...
一, JavaScript 变量的提升
- 函数及变量的声明都将被提升到函数的最顶部
- 变量可以在使用后声明, 也就是变量可以先使用再声明
敲黑板, 划重点, 是变量的声明, 声明, 声明, 当变量或函数已经初始化之后, 就不会提升到函数的最顶部. 这里上面的变量 a 已经初始化了, 所以第一个 console 取不到变量 a 得值, 为 undefined;
注意: 变量的提升只会提升到当前作用域下
二, JavaScript 函数的提升
而函数 b 仅仅是先声明了一个函数方法, 函数 c 是函数表达式无法提升, 所以在严格模式下 b=2;d 报错
对于 m,n, 这里就涉及到 JavaScript 作用域的问题
首先, var m = n = 1 的执行顺序是什么? 并不是我们大多数人心中所想的连续赋值, JavaScript 的赋值是从右向左的, 而是 n=1;var m = n; 很好, 一目了然, 在函数作用域内的变量 m=n,n 是全局变量, 最后严格模式下输出结果, n=1,m 报错;
三, 关于 es6 两个关键字 --let 和 const
let 声明的变量只在 let 命令所在的代码块内有效, 不存在变量的提升
const 声明一个只读的常量, 一旦声明, 常量的值就不能改变. 一旦声明必须初始化, 否则就会报错
来个对比很明显的栗子 (完美的体现出 let 命令只在代码块内有效的意思):
- {
- let test = 2;
- var web = 'font';
- }
- console.log(test); // 报错
- console.log(Web); // font
再次回到上面的题目, c 就是报错的
ES6 明确规定, 代码块内如果存在 let 或者 const, 代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域. 代码块内, 在声明变量 PI 之前使用它会报错.
- var PI = "a";
- if(true){
- console.log(PI); // 报错, 即使函数外面全局声明了 PI, 但在代码块内还是会报错
- const PI = "3.1415926";
- }
以上, 就是关于 JavaScript 中变量提升的理解.
来源: https://www.cnblogs.com/layaling/p/10834108.html