Js中函数作用域问题,看这一篇就够了

在编程语言中,作用域控制着变量与参数的可见性与生命周期。对程序员来说这是一项重要的服务,因为它减少了名称冲突,并且提供了自动内存管理。

 一、从一道面试题入手

var x=10;
function fn(){
  console.log(x)
}
function show(f){
  var x=20;
  f()
}
show(fn);  

这是TX的一道面试题,大家可以思考一下最后打印的结果是什么?

答案是10,那么为啥是10呢,看完这篇博客你就会知道啦~

二、一些规则

其实学习函数作用域,我们必然要记住一些规则,在这里我已经吐血整理好了。一起来看看吧

1.函数外的变量,在函数中可以用

  • 在函数外使用var定义的变量就是全局变量   下面为例子:
var a=10; 
function fn(){
 console.log(a) 
} 
fn(); 

>>10

2.函数内定义的变量不能被函数外调用

  • var是定义变量,如果在函数中没有用var定义变量,直接使用变量,该变量是全局变量
  • 在函数内使用var定义的变量就是局部变量
function fn(){ 
var a=10; 
}
fn(); 
console.log(a); 

>>a is not defined
  • 不使用var直接给一个变量赋值就是相当于给window增加一个属性,这个属性也是全局变量
function fn(){
 a=10;   ​ 
} 
fn(); 
console.log(a); 

>>10
  • 有局部变量时,先调用局部变量
var a=5;
function fn(){
 var a=10;
 console.log(a); 
}
fn();

 >>10

  • 在函数中任意位置使用var定义的变量,在该函数的任意位置都认为该变量是局部变量(下面例子中有局部变量a,但未赋值)
var a=5;
function fn(){
 console.log(a);
 var a=10;
}
fn();

>>undefined  

  • 全局变量和局部变量相加
var a=5;
function fn(){
 var a=10;
 console.log(a+this.a);   //this.表示window下的
}
 fn();


 >>15

  • 参数就是局部变量
function fn(a){
console.log(a);
}
fn(5);
>>5
var a=10;
function fn(a){
console.log(a); //5
var a=20;
}
fn(5);
>>5

三、回到面试题

学习完上面的规则和案例后,我们再次回到开头的面试题:

var x=10;
function fn(){
  console.log(x)
}
function show(f){
  var x=20;
  f()
}
show(fn);  

执行show(fn),fn()被作为参数带入,那么就是执行fn(),fn()函数中并没有局部变量,所以调用全局变量x=10,并将它打印出来,和show()函数中的变量并没有关系,那么最后结果就是10啦。

 

如果觉得还不够意思可以看看下面这几道题哦,(不想看解释的同学请自行忽略掉注释)答案也附着在后面啦。

1、

var a=10;  
//这句代码全局变量a被10覆盖了,即a函数被覆盖了,此时a是一个数值
function a(a){        
//在当前函数所在的script标签创建时,优先将该函数存储在堆中,并且函数名存储在栈中。
console.log(a);
var a=10;
}
a(a);

结果:报错a is not a function

2、

a(a);   //a是全局变量,下面a=10还没有运行,所以在这里全局变量就是函数a,我们把函数a当参数填进去
var a=10;
function a(a){
console.log(a);
var a=10;
}

结果:

>> ƒ a(a){ console.log(a); var a=10; }

3、

var a;
a(a);
a=5;
function a(a){
console.log(a);
var a=10;
}

结果:

>> ƒ a(a){ console.log(a); var a=10; }


欢迎各位大佬指正哦,如果觉得不错就点个赞吧~

你可能感兴趣的:(#,js,前端)