js中的变量提升
一、当我们使用var时 (其实不建议再使用var申明变量,下面说明)
- 首先 我们来看看这段代码,猜测他的运行结果
xixi();
function xixi() {
console.log(a);
}
var a = 1;
/**
答案 ==> 这段代码的运行结果是 undefined
此处知识点就是在JavaScript中,**使用var申明的变量以及
函数**(申明函数本身也是将函数赋值给一个变量)**存在变量提升**,而且使用var申明的变量提升的高度始终在函数之上;
**/
- 我们可以分析一下,如果函数没有提升的话,xixi()调用的时候是还没有这个函数的,但是程序并没有报错,所以是代码在编译的时候对函数进行了一定的提升;
我们再来分析var声明的变量是如何进行变量提升的; 首先我们把上面代码分解一下后等价于下面的代码:
xixi()
function xixi(){
console.log(a);
}
var a ;
a = 1;
然后在编译的时候又会变成如下代码:
var a ;
function xixi(){
console.log(a);
}
xixi()
a = 1;
/**
此处代码就是 var声明的变量的变量提升,我们可以看出 只是提升的声明,赋值 a = 1; 并没有进行提升;
所以代码没有 在 xixi函数调用时 console.log(a)的时候报错
而是打印 undefined (当一个var声明的变量声明了,但是未赋值时取值为undefined)
**/
- 在函数表达式中的提升 其实在函数表达式中声明也是和变量的提升是一样的,但是和function关键字声明的函数有所不同; function关键字声明的是一个函数整体,我们可以理解为声明一个函数同事把函数的地址赋值给了一个变量; 只不过函数声明和函数地址赋值给变量是同时完成的,他们是一个整体,在函数提升中,他们会以一个整体一起提升;
例如下面代码:
function hello() {
console.log('hello~');
}
但是如果我们使用函数表达式声明就不一样了,他和var声明变量是一样的 例如下面代码:
helloGirl()
var helloGirl = function () {
console.log('hello,sgeigei!')
}
//此处会报错,因为提升后相当于
var helloGirl
helloGirl()
helloGirl = function () {
console.log('hello,sgeigei!')
}
此时会报错说 helloGirl 不是一个函数,因为此时她是一个 undefined
推荐使用ES6中的 const以及let 声明变量
我们从上面发现 使用var声明变量可能会因为变量提升给大家带来心智负担,所以我们推荐使用const 以及 let 来声明变量,为什么呢???
首先我们从const 来分析,熟悉ES6的朋友们都知道,const a = 1 以后就不能再给a 赋值了 const 是用来声明常量的; 那么他和var还有什么区别吗?????
//区别一
console.log(a)
const a = 1;
/**
此处会报错,因为const 存在“暂时性死区,其实也就是你在const 声明变量前使用了这个变量”
这里不会像使用var一样打印undefined,他会直接报错;
**/
//区别二
我们使用var时,可以先声明 var a;
但是使用const 必须要为其赋值,否则编译器都会报错;
//区别三
在ES6之前我们只有函数作用域和全局作用域,如下就是函数作用域
例如如下代码:
function a () {
var beauty = 'taoyan'
}
a()
console.log(beauty)
// 此处会报错beauty is not defined,这里就是函数作用域,因为beauty变量是在函数a中声明的,函数运行结束后如果没有形成 闭包 那么这个变量所占的内存就会被回收,这个变量也就不能再被访问到;
但是在ES6开始,引入了块级作用域的概念,我们来看看块级作用域:
块级作用域存在于 大括号之中,也就是说在{}中使用 const 和 let 声明的变量在外部都无法访问
举个例子:
const a = Math.random()
if(a>0.5){
const b = 250
}else{
const b = '250'
}
console.log(b)
此时大家可能觉得我不是人,为什么这样对b,但是你把代码一运行会发现,其实我更狠
这个b无论是 数字的250还是字符串的'250'他都不配,他在{}中,我们在外部拿不到他的值
所以打印会报错,the b is not 250 ,it's not defined
我们在上面提了一下let ,let和const 的区别就只有一点,那就是let 声明的变量可以重复赋值,而且初次声明可以不赋初始值,其他表现和const表现一致;
最后,感谢您的阅读~
JS中的变量提升的理解就只有这些了;
写此文章旨在记录基础知识;
不足之处,大佬们多多指教;