「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
关于JavaScript 中变量和函数声明的提提升,在面试中可能会被问到而且几率还比较大,这里分享一下对JavaScript 中变量和函数声明的提生的理解
什么是变量作用域
变量的生命周期:JavaScript变量的生命周期很简单,从被声明开始,局部变量会在函数运行后被删除,全局变量会在页面关闭后被删除
局部变量:在JavaScript函数内部声明的变量事局部变量,只能在函数内部访问它,可以在不同的函数中使用名称相同的局部变量。
全局变量:在函数外生命的变量是全局变量,网页上所有脚本和函数都能访问它
我们用代码来理解一下:
变量作用域
我们用代码来理解一下它
//demo();这里也可以使用,但是为了新手能理解我们还是在下面使用
function demo(){
var a = 123;
console.log(a);
}
demo();//打印123
如果想全局打印a是打印不到的如下:因为a的作用域仅限于 function demo 想要在全局访问是访问不到的,这也是局部变量在执行完以后被删除后console.log(a)就找不到a的原因
function demo(){
var a = 123;
console.log(a);
}
console.log(a); //a is not defined
如果你定义了一个全局a,在第二个script标签里也可以访问
这里有个给大家看个代码
function demo(){
var a = 123;
b = 456
console.log(a,b);
}
demo();//123 456
console.log(b);//456
console.log(a);//a is not defined
这里b明明在方法里面为什么可以访问到呢,细心的同学可以看到我并没有给b定义var 这里b就会跑到window里面去,console.log(b)就回去window中去找个b 所以是可以找到的 同样window里面也存在了demo方法
没有var定义过的属性可以配置全局属性
<script>
var var1 = 1;//不可配置全局属性
var2 = 2; //没有用var定义,可以配置全局属性
console.log(this.var1); //1
console.log(window.var1);//1
delete var1;//false 无法删除
console.log(var1);//1
console.log(delete var2); //true
console.log(var2); //not defined
</script>
作用域链
这里给大家讲一下关于作用域链的代码
var a = "apple";
var b = "boy";
function demo(){
var a = "vue";
console.log(a); //vue
console.log(b); //boy
}
demo();
console.log(a);//apple
这里是为什么呢,函数里面定义了局部变量a 所以demo里面的log就访问局部变量里面的a:vue 但是没有找到b就会去访问全局变量的b:boy, 而外部的log(a)可以直接访问全局的a:apple
声明提升
用一段代码讲解
var a = "apple";
function demo(){
console.log(a); //undefined
var a = "angle"//局部变量
console.log(a);//angle
}
demo();
为什么会出现这中情况呢 这是因为声明提升,我们肉眼是看不到JavaScript的变量提升的 ,我们把它模拟出来
var a = "apple";
function demo(){
var a;
console.log(a);
a = "angle"
console.log(a);
}
demo();
这就是变量提升后的样子,显而易见,在局部里第一个log(a)找到局部的var a 但是没有赋值所以是undefined,第二个就可以找到a = "angle"
有变量提升自然就有函数提升,我们也用代码来理解一下
var a = "apple";
function demo(){
console.log(a);//undefined
var a = "angle";
console.log(ss()); //angle
function ss(){
return a
}
}
demo();
为什么会出现这种情况,也是因为声明提升造成的,而且函数提升会提升到变量之前,在JavaScript预解析中我们得到这样的代码
var a = "apple";
function demo(){
function ss(){
return a
}
var a;
console.log(a); //undefined
a = "angle";
console.log(ss()); //angle
}
demo();
显而易见的我们可以看到为什么会输出这样的结果
最后用一道题目来讲一下
var b = 'boy';
console.log(b);//boy
function fighting(){
console.log(a);
console.log(c);
if(a === 'apple'){ a= "Alice";}
else{a = "Ada";}
console.log(a);
var a = "Andy";
middle();
function middle(){
console.log(c++);
var c = 100;
console.log(++c);
small();
function small(){console.log(a);}
}
var c = a = 88;
function bottom(){
console.log(this.b);
b="baby";
console.log(b);
}
bottom();
}
fighting();
console.log(b);
相信初学者看到这道题目一定手心发麻,坐立不安,心跳加速,但是我希望大家不要被这道题吓到然后左上角了,因为面试官出的题可能比我这还要变态
首先我们先预解析一下
var b
b = 'boy';
console.log(b);//boy 1
function fighting(){
function middle(){
function small(){console.log(a);} //Andy 7
var c
console.log(c++); //NaN 5
c = 100;
console.log(++c); //101 6
small();
}
function bottom(){
console.log(this.b); //boy 8
b="baby";
console.log(b); //baby 9
}
var a;
var c = a
console.log(a); //undefined 2
console.log(c); //undefined 3
if(a === 'apple'){ a= "Alice";}
else{a = "Ada";}
console.log(a); //Ada 4
a = "Andy";
middle();
c = a = 88;
bottom();
}
fighting();
console.log(b); //baby //10
之后根据我的注释的打印输出顺序,可以慢慢解出这道题目。
这就是我对于JavaScript中变量和函数声明的提升的理解,希望能帮助到大家