JavaScript 其實是一門編譯語言
ES5 引入“嚴(yán)格模式”,嚴(yán)格模式禁止自動或隱式地創(chuàng)建全局變量
影響性能的欺騙詞法
第一種方式:動態(tài)生成代碼
function foo(str, a) {
eval( str ); //欺騙!
console.log( a, b);
}
var b = 2;
foo( "var b = 3;", 1); // 1, 3
注意:在嚴(yán)格模式下,eval() 在運行時有其自己的作用域,其中的聲明將不會修改其他作用域中的聲明。
第二種方式:with 關(guān)鍵字
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = {
a: 3
};
var o2 = {
b: 4
};
foo(o1);
console.log(o1.a); // 2
foo(o2);
console.log(o2.a); // undefined
console.log(a); // 2
規(guī)避變量名沖突的方法
- 全局命名空間
在全局作用域中申明一個對象變量,用作庫的命名空間。 - 模塊管理
始終給函數(shù)表達式命名是最佳實踐
IIFE,立即執(zhí)行函數(shù)表達式,的三個作用
- 隔離作用域,維護代碼風(fēng)格
var a = 2;
(function IIFE( global ) {
var a = 3;
console.log(a); // 3
console.log(global.a); // 2
})(window);
console.log(a); // 2
- 解決undefined的默認值被錯誤覆蓋導(dǎo)致的異常
(function() {
var undefined = true;
(function IIFE(undefined) {
var a;
if (a === undefined) {
console.log(a === undefined); // true
}
})();
var a;
console.log(undefined); // true
console.log(a === undefined); // false
})();
While it is possible to use it as an identifier (variable name) in any scope other than the global scope (because undefined
is not a reserved word
)
- 倒置代碼的運行順序
var a = 2;
(function IIFE(def) {
def(window);
})(function def(global) {
var a = 3;
console.log(a); // 3
console.log(global.a); //2
});
塊作用域
沒有必要把只在某一個區(qū)域內(nèi)生效的變量污染到整個函數(shù)作用域中。
實現(xiàn)塊作用域的方法:
- with
- try/catch catch語句會創(chuàng)建一個塊作用域,其中生命的變量僅在catch中生效
- let關(guān)鍵字可以講變量綁定到所在的任意作用域中。只要生命是有效的,在生命中的任意位置都可以使用{...}來為let創(chuàng)建一個用于綁定的塊,最好顯式創(chuàng)建作用塊。需要注意的是,let聲明代碼被運行之前,聲明并不存在
var foo = true;
if (foo) { // <-- 可以作為隱式的塊
{ // <-- 顯式的塊
console.log(bar); // undefined
let bar = foo * 2;
console.log(bar); // 2
}
console.log(bar); // "ReferenceError: bar is not defined
}
Constants are block-scoped, much like variables defined using the let
statement.