轉發請標明來源:http://www.cnblogs.com/johnhou/p/javascript.html 請尊重筆者的勞動成果 --John Hou
在javascript中有多種方法可以讓一段字符串當做一段js代碼來執行:
- 使用eval("要執行的字符串")
- 使用new Function("要執行的字符串")
- setTimeOut("要執行的字符串",500)
- setInterval("要執行的字符串",500)
當然根據javascript最佳實踐,我們是不推薦上面的任何一種方式的,當然eval()在處理JSON串時還是必須使用的,但是最佳實踐禁止使用new Function構造函數來創建函數,而且禁止給setTimeout()和setInterval()方法傳遞字符串,應該傳遞函數名。
一、eval和new Function()的區別:
console.log("執行Function");
var val = new Function("console.log('houquan')");
console.log(typeof val);
console.log(val);
val();//如果不調用,那么就永遠也不會輸出“houquan”
/**
通過new Function("...")執行返回的結果是一個名為anonymous的函數,函數體就是傳到new Function()中的字符串。
anonymous的中衛意思是:匿名的
*/
val = new Function("(function(){console.log('test');})()");
console.log(typeof val);
console.log(val);
val();
new Function("alert('test1')");
eval("alert('test2')");
/**
new Function()和eval()的區別是,前者把傳入的字符串封裝為一個function對象
的語句返回,直到調用這個返回的函數時,才會執行字符串所要執行的操作;后者則是
直接把字符串當做js代碼執行,返回的結果是一個Object對象。
*/
console.log("執行eval");
val = eval("console.log('houding')");
console.log(typeof val);
console.log(val);
/**
eval的執行結果在FireFox下是一個對象,在IE8中不返回結果
該對象在FireFox中的結構如下:
*/
執行結果:
FireFox下的執行結果
IE8下的執行結果:
二、使用eval的注意事項:
console.log("第一個執行");
try{
eval("function(){console.log('error');}");
}catch(e){
console.log("error1");
console.log(e.toString());
}
/**上面代碼執行的結果就類似於在全局作用域中定義一個匿名函數是一個道理,
果斷報錯,這就相當於給全局對象window,添加一個匿名的屬性,或者方法一
樣,顯然是無法做到的!
*/
console.log("第二個執行");
try{
eval("(function(){console.log('right')})()");
}catch(e){
console.log("error2");
console.log(e.toString());
}
/**
上面的代碼就相當於執行一個即時函數一樣
*/
console.log("第三個執行");
try{
eval("function test(){console.log('test');}");
test();
}catch(e){
console.log("error3");
console.log(e.toString());
}
/**
上面的代碼相當於定義一個函數
*/
執行結果:
eval 執行創建對象字面量注意事項
console.log("錯誤的創建對象字面量的情況");
try{
eval("{name:'houquan'}");
}catch(e){
console.log("error");
console.log(e.toString());
}
/**
上面的代碼等同於下面的代碼
*/
name:"houquan";
console.log("正確的創建對象字面量的情況");
try{
eval("({name:'houquna'})");
}catch(e){
console.log("error0");
console.log(e.toString());
}
/**
上面第一段代碼中javascript引擎把{}中檔次代碼塊來執行,所以不會返回
預期的對象
應該把對象字面量的創建語句用()括起來,當成一個表達式來執行,這樣
就能得到正確的結果了。
*/
執行結果:
單獨執行
try{
eval("{name:'houquan'}");
}catch(e){
console.log("error");
console.log(e.toString());
}
執行結果:
以下是我的微信公眾號,技術大牛集結號,歡迎您的關注!