重學前端-閉包和執行上下文

說明

重學前端是程劭非(winter)在極客時間開的一個專欄,在此主要整理個人學習筆記。若有侵權,請聯繫我,謝謝。javascript

執行上下文在不一樣版本的概念

var聲明與賦值

var聲明可以穿透if、for等語句前端

當即執行函數,經過聲明一個函數,而且當即執行,來構建一個新的域。來控制var的範圍java

語法規定function關鍵字開頭是函數聲明,爲了變成函數表達式,能夠在前面加東西。es6

  • 加括號
(function(){
    var a;
    //code
}());


(function(){
    var a;
    //code
})();
複製代碼

加括號有個缺點,就是若是在最後不加分號,括號會被解釋爲上一行代碼最末的函數調用。所以有些作法是c#

  • 加前面加分號
;(function(){
        var a;
        //code
    }())
    
    
    ;(function(){
        var a;
        //code
    })()
複製代碼
  • void 關鍵字法
void function(){
        var a;
        //code
    }();
複製代碼

void表示忽略後面表達式的返回值,變成undefined,在使用當即執行函數時,咱們並不關係函數的返回值bash

在with用法裏, var 的特性會致使聲明的變量和被賦值的變量是兩個 bapp

var b;
void function(){
    var env = {b:1};
    b = 2;
    console.log("In function b:", b); // 2
    with(env) {
        var b = 3;  
        console.log("In with b:", b); //3
    }
}();
console.log("Global b:", b); // undefined
複製代碼

在with聲明的b做用到了外部function的環境上,對兩個域(with和function)產生了做用,這是用with的弊端。函數

這裏我修改一下,看看不一樣的寫法,b的值有什麼不一樣學習

var b;
void function(){
    var env = {b:1};
    b = 2;
    console.log("In function b:", b); //2
    var b = 3;
}();
console.log("Global b:", b);  //undefined
複製代碼

這個時候b仍是不一樣,由於在當即執行函數裏用了var關鍵字聲明瞭b,全部b=2賦值的是該做用域的b,不是全局做用域的b。spa

var b;
void function(){
    var env = {b:1};
    b = 2;
    console.log("In function b:", b);   //2
}();
console.log("Global b:", b);  //2
複製代碼

這個時候b是同一個b。這個是做用域鏈在查找變量的時候,若是在內部的做用域找到這個變量的,就會中止查找,若是找不到,會去外層做用域繼續查找,直到找到爲止。

let

let是es6引入的新的變量聲明模式,爲了實現let,es6在運行時引入了塊級做用域

如下語句會產生let使用的做用域:

  • for
  • if
  • switch
  • try/catch/finally

Realm

新概念。

Realm中包含一組完整的內置對象,並且是複製的關係

var iframe = document.createElement('iframe')
document.documentElement.appendChild(iframe)
iframe.src="javascript:var b = {};"

var b1 = iframe.contentWindow.b;
var b2 = {};

console.log(typeof b1, typeof b2); //object object

console.log(b1 instanceof Object, b2 instanceof Object); //false true
複製代碼

b1和b2是由一樣的代碼在不一樣的Realm中執行,在用instanceof是會有不一樣的行爲。

相關文章
相關標籤/搜索