在編程語言中,作用域控制着變量與參數的可見性與生命週期。對程序員來說這是一項重要的服務,因爲它減少了名稱衝突,並且提供了自動內存管理。
一、從一道面試題入手
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; }
歡迎各位大佬指正哦,如果覺得不錯就點個贊吧~