就是變量聲明的區域,就是變量和函數的可訪問範圍javascript
在全局做用域中聲明的變量叫作全局變量,全局做用域的變量能夠在js中任何地方調用 ,變量沒有在函數內聲明或者聲明的時候沒有帶var就是全局變量,擁有全局做用域。特殊:var a = b = c = 0; b與c是全局變量。
java
如,在函數內部聲明的變量只能在函數內部訪問es6
在javascript中,函數裏面定義的變量,能夠在函數裏面被訪問,但在函數外沒法訪問。而由花括號封閉的代碼塊都有本身的做用域,於是支持根據條件來定義變量,變量在執行完畢後會被銷燬,注意在es6以前的版本,並無塊級做用域,只有函數做用域和全局做用域
,for循環的循環體中是函數做用域,for循環內部定義的變量在整個所在的函數內部是能夠訪問的。bash
舉個栗子
函數
for(var i =0;i<10;i++){
//console.log(i)
}
console.log(i) //這裏i打印爲10,i的做用域是全局做用域
複製代碼
var t = 9;
function f1() {
var t2 = 10;
console.log(t);
console.log(t3)
function f2() {
var t3 = 200;
console.log(t2);
return t2 * t2;
}
return f2()
}
f1();
複製代碼
這樣就造成了一個做用域鏈f2.Scope ===> f1.Scope ===> global.Scope
ui
函數在執行的時候會沿着最末端的做用域依次向上查找變量,所以,子域能夠訪問父域的變量,而父域不能夠訪問子域的
es5
上述代碼的執行結果爲spa
var t = 9;
function f1() {
var t2 = 10;
console.log(t);//9
console.log(t3)//父級不能夠訪問子級的變量。報錯 not defined
function f2() {
var t3 = 200;
console.log(t2); //10
return t2 * t2;
}
return f2()
}
f1();
複製代碼
若是一個聲明的變量在函數體內,那麼它的做用域就是函數內部。若是是在全局環境下聲明的,那麼它的做用域就是全局的。經過var聲明的變量是沒法用delete刪除的。code
函數內部的聲明的變量會被提高到函數的頭部。函數在解析執行的時候,先進行變量聲明處理,而後再運行函數內部的代碼。ip
變量和賦值語句一塊兒書寫,在js引擎解析時,會將其拆成聲明和賦值2部分,聲明置頂,賦值保留在原來位置
function a(){
var b = 1
}
複製代碼
上述代碼就至關於
function a(){
var b
b = 1
}
複製代碼
變量重複聲明不會出錯,後面的會覆蓋前面的。
var a = 1
var a = 2
console.log(a)//被覆蓋,a的值爲2
複製代碼
當函數名和變量名相同時, 函數 > 變量,也就是先函數提高,後變量提高
var a = 1
function a(){
}
console.log(a)//a打印1
複製代碼
既然是先函數提高後變量提高那爲何會打印變量的值呢,由於,重複聲明是會被後面的覆蓋的
上述代碼至關於
var a = function(){
}
var a = 1
console.log(a)//a打印1
複製代碼
咱們來看幾個題目在鞏固一下做用域和變量提高
if (!("a" in window)) {
var a = 1;
}
console.log(a);
複製代碼
if (!("a" in window)) {
var a = 1;
}
console.log(a);//undefined
複製代碼
1."a" in window是判斷在全局做用域中存不存在a,若存在則爲true,不存在爲fasle
2.在es5中函數是沒有塊級做用域的,所以在if中定義的變量的做用域爲包括此if語句的做用域,即變量a的做用域爲全局做用域
3.在js執行過程當中會先進行變量提高,所以在全局中先聲明一個變量a
4.if()的判斷爲false,所以不會a不會賦值
5打印a爲undefined
var a
if (!("a" in window)) { // true
a = 1;
}
console.log(a);//undefined
複製代碼
var a = 18;
function d() {
console.log(a);
var a = { age: 19};
console.log(a);
}
d(); // 輸出?
console.log(a);
複製代碼
var a = 18;
function d() {
console.log(a);//undefiend
var a = { age: 19};
console.log(a); //{ age: 19};
}
d(); // 輸出?
console.log(a);//18
複製代碼
在訪問變量時會先在訪問的做用域進行查找
1.函數d在執行的時候,遇到var a = {age:19}時進行了變量提高,只聲明沒有賦值,所以第一個打印語句打印undefined
2.全局中的a在全局中查找,打印18
//至關於
var a
a = 18;
function d() {
var a
console.log(a);//undefiend
a = { age: 19};
console.log(a); //{ age: 19};
}
d(); // 輸出?
console.log(a);//18
複製代碼
練習1
console.log(a);
var a = 20;
console.log(a);
function a() {
}
複製代碼
練習2
f();
console.log(a);
console.log(b);
console.log(c);
function f() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
複製代碼
練習3
f();
function f() {
for(var k = 0; k <10; k++) {
console.log(k);
}
console.log(k);
}
複製代碼
console.log(a); //打印函數a
var a = 20;
console.log(a); //20
function a() {
}
複製代碼
f();
console.log(a);//Uncaught ReferenceError: a is not defined
console.log(b);//若是代碼能夠執行到這裏(忽略上述行的報錯),打印9
console.log(c);//若是代碼能夠執行到這裏(忽略上述行的報錯),打印9
function f() {
var a = b = c = 9;
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
複製代碼