1. 程式人生 > 程式設計 >JS中作用域以及變數範圍分析

JS中作用域以及變數範圍分析

變數作用域

js作為一門指令碼語言,他與c,java這些語言是不相同的。

全域性變數

在js中宣告全域性變數,有下面幾種方式:

1.在函式外通過var來宣告。

var test ="hello";
console.log(test);
function a(){
  test="xx";
  console.log(test);
}
a();
console.log(test);

結果:

hello
xx
xx

這種方式通過宣告的變數在任何地方都可進行修改和使用。

2.在函式中隱士的宣告變數

function a(){
  test=22;
  console.log(test);
}
a();
console.log(test);

結果:

22
22

因為js是弱型別指令碼語言,在使用之前無需定義,所以可以通過這種方式也能宣告全域性變數。

來看一個反例:

var test="aa";
console.log(test);
function a(test){
  test=22;
  console.log(test);
}
a(test);
console.log(test);

結果:

aa
22
aa

可以看到在函式中修改了test值可是第二次在函式外列印的值沒有變。這是因為在函式的過程中只是進行了值傳遞。區域性變數覆蓋掉了全域性變數,只是區域性變數 在 修改。

因為在函式的引數內定義的變數並不是全域性變數。

反例二:

function a(){
  var test="aa";
  console.log(test);
}
a();
console.log(test);

結果

aa
notdefine

在函式內通過var來宣告的變數是區域性變數,函式外無法訪問。

變數作用域

js的作用域和c與java這些語言的作用域也不相同,騷小孩在以前經常會因為這個而頭疼,後來在認真學習了以後才懂了。

1.js中沒有塊範圍。

if(1!=1){
  var y=c;
}
console.log(y)
 
if(1==1){
  var x=a;
}
console.log(x);

結果:

undefine

a

可以看到在if程式碼塊定義的兩個變數,在if塊之外去列印,如果判斷成功的話,才會去執行裡邊的宣告語句,宣告語句執行了,那麼在程式碼塊外邊就可訪問到了。

也可以看出在程式碼塊中宣告的變數也是全域性變數。

2.js中的全域性變數都會成為window的屬性

var x=0;
console.log(window.x);

結果:

0

3.變數提升

var c=0;
function a(){
  console.log(c);
}
a();

結果:

0

var c=0;
function a(){
  console.log(c);
  var c=11;
}
a();

結果:

undefine

可以看出在函式中加了一行宣告語句結果就會不同,這產生這樣的原因是什麼呢?

其實第二個程式碼塊的執行順序是這樣的:

var c=0;
function a(){
  var c;
  console.log(c);
  c=11;
}
a();

在函式中他會先把宣告語句提升到第一行,但是並不提升賦值。然後區域性變數覆蓋全域性變數,在列印c的時候區域性變數還沒來的

及賦值所以就是undefine。

變數提升不只會提升會執行的變數,不會執行的變數也會進行提升:

var c=10;
function a(){
  console.log(c);
  if(false) {
    var c = 10;
  }
}
a();

結果:

undefine

因為在if判斷中定義了局部變數c,雖然if條件不成立,但是也會進行變數提升,所以列印c也是undefine;

4.let變數

通過上面的例子可以看到用var來定義變數的弊端:

1.var定義的變數沒有塊作用域;

2.var定義的全域性變數會自動新增全域性window物件的屬性;

3.var變數會提前裝載(變數提升);

let就是為了解決這些問題而誕生的。

for(let i=0;i<5;i++){
  
}
console.log(i);

結果:

報錯

在程式碼塊中定義了let變數,在外部引用的時候不會存在。即存在塊作用域。

let i=10;
console.log(window.i);

結果:

undefine

let宣告的變數並不會成為window的屬性。

var c=10;
function a(){
  console.log(c);
  let c=1;
  console.log(c);
}
a();

在函式中存在變數與全域性變數名相同的c,因此會覆蓋掉全域性變數c,但是由於let不會提前裝載,所以在第一個列印語句列印c時會報錯。

到此這篇關於JS中作用域以及變數範圍分析的文章就介紹到這了,更多相關JS變數作用域內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!