作用域與閉包

2022-08-27 19:42:12 字數 2525 閱讀 4950

變數存在並產生作用的環境上下文。在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 上面的 有三個執行上下文環境...