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; }


歡迎各位大佬指正哦,如果覺得不錯就點個贊吧~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章