變數存在並產生作用的環境上下文。在es5規範中只有兩種作用域
函式可以巢狀,而每個函式都有自己的作用域,當進入乙個函式的時候,函式環境就會被壓入乙個環境棧當中,當函式執行完畢之後又會出棧,將控制權轉交給外面一層的函式。
// 內部呼叫外部
var a = 3;
function add()
add()
console.log(a); // 4
// 外部呼叫內部
function add()
b = b + 1;
console.log(b); // b is not defined
var a = 10;
function fn()
fn() // 20
var a = 10;
function fn1()
function fn2()
fn2(); // 10
上面**最終輸出了全域性物件的a而不是fn2當中的a。
console.log(a); // undefined
var a = 10;
上面的**等價於
var a;
console.log(a); // undefined
a = 10;
函式也會被提公升,並且作為js的一等公民,函式優先被提公升
fn() // 2
var fn = function ()
function fn()
如上**所示,會輸出2,這證明函式會被先提公升到頭部,這裡如果將函式宣告都刪除只留下宣告和賦值fn的語句則會報錯not a function
,原因在於函式宣告沒了就會將變數提公升,而變數提公升上去的話還沒有賦值為函式。
塊級作用域使得**更加的優雅、簡潔、可維護,例如for
迴圈,從邏輯上來講在通常使用for
迴圈時候我們更希望的是它裡面是擁有自己的作用域。其中的變數只在for
迴圈當中起作用,但是在for
迴圈當中沒有塊級作用域,因此繫結的是外部作用域。下面例子當中,可以看出for
迴圈繫結的是全域性作用域,因此i
成為了window
的屬性。
for (var i = 0; i < 3; i++)
console.log(window.i); // 3
在es5的規範當中,有兩種方法可以建立塊級作用域。
var a = ;
function fn(obj)
console.log(b); // 2
}fn(a);
console.log(a.count); // 2
如上**所示,將a物件傳入with,在其中改變count,最後輸出a.count已經變成了2,說明with當中的count是物件a的,而在with宣告的b,被繫結到外部作用域,所以在外面輸出為2了。且在with當中宣告同物件當中的同名變數var會被忽視。
es6新增了兩個宣告方式可以用於建立塊級作用域
console.log(a); // 報錯
console.log(b); // 10
let還有不存在變數提公升
+未宣告前不可使用
的特性
const obj =
obj.a = 2;
console.log(obj.a); // 2
js高程3當中對於閉包的定義是有權訪問另乙個函式作用域中的變數的函式
,當然這裡的前提是這個閉包函式不被巢狀在該函式作用域當中,否則就不是特權了,而只是沿著作用域的查詢。乙個簡單的閉包如下:
function fn()
return geta;
}var f = fn();
f(); // 10
function counter()
return add;
}var btn = counter();
btn(); // 1
btn(); // 2
function counter()
function setnumber(num)
function getcount()
return ;
}var btn = counter();
btn.get(); // 0
btn.add(); // 1
btn.setnumber(5); // btn.setnumber is not a function
以上**當中,在函式當中定義了乙個變數,三個方法,但是只返回了兩個方法,當呼叫未返回的方法的時候發生了錯誤。 作用域與閉包
執行上下文 範圍 一段或者乙個函式 全域性 變數定義 函式宣告 一段 函式 變數定義 函式宣告 this arguments 函式 ps 注意 函式宣告 和 函式表示式 的區別 console.log a var a 100 fn zhangsan function fn name this thi...
作用域 閉包
1.js執行順序 語法分析 預編譯 先生成go物件 1.函式執行生成ao物件 2.形參和變數作為ao物件的鍵名,鍵值是undefined 3.實參賦值給形參 4.在函式中找到函式宣告,把函式作為ao物件的屬性名,屬性值為函式體 執行js 作用域 變數作用範圍 1.作用域 變數作用範圍 1 函式作用域...
JS作用域與閉包
vo ao 的解釋 1.作用域 es5中只有全域性作用域和函式作用域,我們都知道他沒有塊級作用域。es6中多了乙個let,他可以保證外層塊不受內層塊的影響。即內層塊形成了乙個塊級作用域,這是let的乙個特點。var a 1 function f1 f2 f1 2,1,2 上面的 有三個執行上下文環境...