前端面試必考知識點梳理-作用域、閉包

趁熱打鐵,今天簡單談一談作用域和閉包,老規矩請看面試題:

1.說一下對變量提升的理解

2.說明this幾種不同的使用場景

3.創建10個<a>標簽,點擊時彈出對應的序號

4.如何理解作用域

5.實際開發中閉包的使用



知識點:執行上下文? ? this? ? 作用域? ? 作用域鏈? ? 閉包

1.執行上下文

? ? 范圍:一段<script>或一個函數

? ??一段<script>:變量定義? ? 函數聲明? ?(會先被讀取)

? ? 函數:變量定義? ? 函數聲明? ? this? ? arguments(會先被讀取),注意函數聲明(function abc(){})和函數表達式(var abc = function (){})的區別

? ? 例1:????console.log(a)? ? ?????var? a = 100? ? ? //? ?undefined

? ? 例2:????a? ?= 100? ? ?console.log(a)? ? ? var? a??????????//? ?100?

? ? 例3:????fn('zhangsan')? ? //? ? ? ?zhangsan? ?20

? ? function fn(name) {

? ? ? ? age = 20

? ? ? ? console.log(name,age)? ? ? ? ?

? ? ? ? var age? ?

????}

2.? ? this

this要在執行時才能確認值,定義時無法確認,具體如下:


this指向:a? ? 構造函數中執行? ?this指向空對象,給this賦值

? ? ? ? ? ? ? ? b? ? 作為對象屬性賦值? ? 指向這個對象

? ? ? ? ? ? ? ? c? ? 普通函數中執行? ? ? ? 指向window

? ? ? ? ? ? ? ? d? ? call? apply? bind中使用? fn.call({x:100},'abc');fn函數中的this就是傳入的{x:100}

3? ? 作用域

3.1????JS中沒有塊級作用域 if (true) { var a = 100};? console.log(a)? ?//? ?100? 仍然能打印出a的值

3.2? ? 函數作用域、全局作用域(函數作用域是封閉的,不會受到外邊變量影響)

? ? ? ? ?var a = 200;

? ? ? ? ?function? fn() {

? ? ? ? ? ? var a = 100;

? ? ? ? ? ? console.log(a)

????????}

? ? ? ? console.log(a)? ?//? ?200

? ? ? ? fn();? ?//? ? 100? ? ? ??

3.3? ? 作用域鏈

? ? ? ? var a = 100;

? ? ? ? function fn() {

? ? ? ? ? ? //? ?當前作用域沒有定義的變量,即自由變量,去父級作用域查找

? ? ? ? ? ? console.log(a)

????????}

? ? ? ? fn();? //? ? 100

? ? ? ? 父級作用域:函數被定義的作用域,不是被執行時的作用域

上圖中以console.log(a)為例講一下。在F2函數體中沒有a這個變量,那么去它的父級作用域查找,F2是在F1函數體中被定義的(注意哦,是被定義的作用域不是執行的作用域),其中只定義了b變量,所以繼續向上找,F1是在全局被定義的,全局定義了變量a,所以a打印出來是100;

3.4? ? 閉包的使用場景

a? ? 函數作為返回值

? ? ? ? function F1() {

? ? ? ? ? ? var a = 100;

? ? ? ? ? ? return function () {

? ? ? ? ? ? ? ? console.log(a)

????????????}

????????}

? ? ? ? var f1 = F1();

? ? ? ? var a = 200;

? ? ? ? f1();? ? //? ?100? ?自由變量去父級作用域查找? 全局的a=200無用

b? ? 函數作為參數傳遞

?????function F1() {? ??????

????????var a = 100;

? ? ? ? ? ? return function () {

????????????????console.log(a)

????????????}

? ? ? }

? ? ? ? var f1 = F1();

? ? ? ? function F2(fn) {

? ? ? ? ? ? var a = 200;

? ? ? ? ? ? fn();

????????}

? ? ? ? F2(f1);? //? ?打印出來的 還是100? ? 原因同上? ?自由變量去父級作用域查找? a=200無用


解答:

1.說一下對變量提升的理解

? ? 這問的就是執行上下文,變量聲明的東西,注意函數聲明和函數表達式的區別

2.說明this幾種不同的使用場景

????a? ? 構造函數中執行? ?this指向空對象,給this賦值

????b? ? 作為對象屬性賦值? ? 指向這個對象

????c? ? 普通函數中執行? ? ? ? 指向window????

? ? d? ? call? apply? bind中使用? fn.call({x:100},'abc');fn函數中的this就是傳入的{x:100}

3.創建10個<a>標簽,點擊時彈出對應的序號

? ? 這道題考的是閉包,像下邊這樣的寫法是錯的,alert出來的都是9,因為當你點擊的時候,alert(i)這個i變量是自由變量,會去父級作用域查找,父級作用域的i已經是9了。

這樣的寫法才是正確的,alert的i是自由變量,會去父級作用域查找


4.如何理解作用域

? ? a? ? 自由變量

? ? b? ? 作用域鏈,即自由變量的查找

? ? c? ? 閉包的兩個場景

5.實際開發中閉包的使用

? ? 主要用于 封裝變量? 收斂權限;用在循環中,如問題3;

下期預告:異步? ? 單線程? ?敬請期待

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容