重學前端是程劭非(winter)在極客時間開的一個專欄,在此主要整理個人學習筆記。若有侵權,請聯繫我,謝謝。javascript
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 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是es6引入的新的變量聲明模式,爲了實現let,es6在運行時引入了塊級做用域
如下語句會產生let使用的做用域:
新概念。
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是會有不一樣的行爲。