從[[scope]]說閉包

閉包

詞法作用域是在定義時(shí)確定的: [[scope]]
上下文是函數(shù)執(zhí)行時(shí)的變量環(huán)境: vo + [[scope]]
所以閉包執(zhí)行的時(shí)候是通過[[scope]]來訪問作用域鏈上的變量。

函數(shù)的從聲明到執(zhí)行的過程:

  • 創(chuàng)建(引擎準(zhǔn)備并填充三個(gè)變量)
    + vo:函數(shù)參數(shù),內(nèi)部變量, 函數(shù)內(nèi)部聲明
    + scope chain: 作用域鏈
    + 確定this的值并填充
  • 執(zhí)行
  • 詞法作用域
    代碼創(chuàng)建時(shí)定義的靜態(tài)作用域
  • 上下文
    代碼運(yùn)行時(shí),this的指向

作用域鏈(函數(shù)定義的時(shí)候確定):

每個(gè)函數(shù)在定義的時(shí)候都有一個(gè)[[scopes]]屬性,指向的是它的作用域鏈。直到函數(shù)銷毀。其中closure是閉包,script指向自身變量,global指向全局變量

[[Scopes]]: Scopes[3]
         0: Closure (foo) {y: 20}
         1: Script {bar: ?}
         2: Global {postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window, 
     function foo() {
         alert(x);
     }
     
     (function () {
         var x = 20;
         foo(); // 10, but not 20
     })();
     var x = 10;
     // 通過Function構(gòu)造的函數(shù),不能訪問閉包變量,只能訪問全局變量,[[scope]]作用域鏈沒有closure
     function foo() {
     
     var y = 20;
     
     function barFD() { // 函數(shù)聲明
         alert(x);
         alert(y);
     }
     
     var barFE = function () { // 函數(shù)表達(dá)式
         alert(x);
         alert(y);
     };
     
     var barFn = Function('alert(x); alert(y);');
     
     barFD(); // 10, 20
     barFE(); // 10, 20
     barFn(); // 10, "y" is not defined
     
     }
     
     foo();
     // 變量查找= 作用域鏈查找(直到global沒有找到) + 原型鏈查找
     function foo() {
     // var x = 20;
     
     function bar() {
         alert(x);
     }
     
     bar();
     }
     
     Object.prototype.x = 10;
     
     foo(); // 20

 ```
* 在代碼執(zhí)行階段有兩個(gè)聲明能夠修改作用域鏈:
     * with
     * catch
 ``` javascript
 // 普通的閉包的作用域鏈在定義的時(shí)候確定,不能修改參數(shù)的調(diào)用值
     var x = 10;
     function foo() {
         alert(x);
     }
     (function () {
         var x = 20;
         foo(); // 10, but not 20
     })();
 // 使用with之后,with綁定的對(duì)象推到作用域鏈的最前端,同時(shí)再進(jìn)行變量賦值,能夠改變參數(shù)的調(diào)用值
     var x = 10, y = 10;

     with ({x: 20}) {
     
     var x = 30, y = 30;
     
         alert(x); // 30
         alert(y); // 30
     }
     
     alert(x); // 10
     alert(y); // 30
 ```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容