JavaScript 2、eval 和 with 函數

/* * ========================================================= * * JavaScript 詞法欺騙 * * 1.欺騙詞法做用域,會致使性能降低。 * 2.引擎在代碼中發現了,eval()和 with()函數時,引擎在詞法階段並不知道它們將接收的什麼代碼,引擎只能簡單的假設關於標示符是無效的。 * 3.在javascript中編譯源代碼時,其中一步是對代碼作大量的優化,當遇到上述兩個函數時,引擎只能不作任何代碼的優化,這個是下降性能的緣由。 * 4.eval()和 with()函數,都將在運行時起到做用。 * * ========================================================= * */// function foo(str, a) {//   eval(str); // 欺騙詞法//   console.log(a, b); // 1 3// }//// var b = 2;//// foo("var b = 3;", 1);//// var obj = {//   a: 1,//   b: 2,//   c: 3// };//// console.log(obj.a);// console.log(obj.b);// console.log(obj.c);// with 一般被看成重複引用同一個對象中的多個屬性的快捷方式。// 但不推薦使用,因會改變當前做用域,下降性能,而且可能形成變量泄漏。// 不用循環的重複的調用對象自己。// with (obj) {//   a = 3;//   b = 4;//   c = 5;// }//// console.log(obj.a);// console.log(obj.b);// console.log(obj.c);// with// 首先咱們知道a = 2; 是一個賦值操做(LHS)。當foo傳入一個引用(obj),with會改變該// 引用做用域中的a屬性值,當在該引用查找不到a變量時,做用域查找方式起到做用,向上層做用域執行查找a變量// 在該引用做用域、foo做用域、全局做用域中,都沒有找到a變量時,with 就自動建立了一個全局變量(若是在上述做用域中查找到a變量將會改變其變量值),// 這也叫作變量泄漏,形成這個緣由是a=2 執行的時賦值操做,根據javascript中的特性,賦值操做前沒有見變量聲明標示符時,javascript就自動建立一個全局變量。// 前提是非嚴格模式下,纔會產生以上內容,嚴格模式下,將徹底禁止使用with函數。// with 其實是根據你傳遞給它的對象引用,憑空的建立出一個全新的詞法做用域。// var a = 10; // 這裏能夠驗證with更改了a變量的值。若是沒有定義這個變量,console.log( a );打印的也是2.// function foo(obj) {//   with (obj) {//     a = 2; // 徹底等於賦值操做//   }// }// var o1 = {a: 3};// var o2 = {b: 3};// foo(o1);// console.log(o1.a); // 2//// foo( o2 );// console.log( o2.a ); // undefined// console.log( a ); // 2——很差,a 被泄漏到全局做用域上了!
相關文章
相關標籤/搜索