ตัวอย่างเช่น;
var s = "function test(){
alert(1);
}";
var fnc = aMethod(s);
ถ้านี่คือสตริงฉันต้องการฟังก์ชันที่เรียกว่า fnc และfnc();
ปรากฏหน้าจอแจ้งเตือน
eval("alert(1);")
ไม่สามารถแก้ปัญหาของฉันได้
ตัวอย่างเช่น;
var s = "function test(){
alert(1);
}";
var fnc = aMethod(s);
ถ้านี่คือสตริงฉันต้องการฟังก์ชันที่เรียกว่า fnc และfnc();
ปรากฏหน้าจอแจ้งเตือน
eval("alert(1);")
ไม่สามารถแก้ปัญหาของฉันได้
คำตอบ:
ฉันเพิ่มการทดสอบ jsperf สำหรับ 4 วิธีในการสร้างฟังก์ชันจากสตริง:
ใช้ RegExp กับคลาสฟังก์ชัน
var func = "function (a, b) { return a + b; }".parseFunction();
การใช้ฟังก์ชันคลาสกับ "return"
var func = new Function("return " + "function (a, b) { return a + b; }")();
ใช้ตัวสร้างฟังก์ชันอย่างเป็นทางการ
var func = new Function("a", "b", "return a + b;");
ใช้ Eval
eval("var func = function (a, b) { return a + b; };");
วิธีที่ดีกว่าในการสร้างฟังก์ชันจากสตริงคือการใช้Function
:
var fn = Function("alert('hello there')");
fn();
สิ่งนี้มีข้อดี / ข้อเสียที่ตัวแปรในขอบเขตปัจจุบัน (ถ้าไม่ใช่ทั่วโลก) ไม่นำไปใช้กับฟังก์ชันที่สร้างขึ้นใหม่
สามารถส่งผ่านข้อโต้แย้งได้เช่นกัน:
var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'
Function
คุณไม่ก่อให้เกิดมลพิษในขอบเขตท้องถิ่นและนี่คือสาเหตุที่eval
ทำให้การเพิ่มประสิทธิภาพเป็นเรื่องยากสำหรับเครื่องยนต์ ... ด้วยตัวอย่าง OP ฉันจะ:var fnc = Function('return '+s)();
element.onclick = function() { alert("test"); }
ไฟล์.
คุณค่อนข้างใกล้
//Create string representation of function
var s = "function test(){ alert(1); }";
//"Register" the function
eval(s);
//Call the function
test();
นี่คือซอที่ใช้งานได้
eval
คำเตือนบังคับสำหรับผู้ค้นหาในอนาคต: eval
สามารถเปิดช่องโหว่สำหรับแฮ็กเกอร์: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…แต่ถ้าคุณรู้ถึงอันตรายและสามารถหลีกเลี่ยงได้นี่เป็นวิธีง่ายๆที่ดีในการ สร้างฟังก์ชันจากสตริง
ใช่การใช้Function
เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่เราสามารถไปได้ไกลกว่านั้นและเตรียมตัวแยกวิเคราะห์สากลที่แยกวิเคราะห์สตริงและแปลงเป็นฟังก์ชัน JavaScript จริง ...
if (typeof String.prototype.parseFunction != 'function') {
String.prototype.parseFunction = function () {
var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
var match = funcReg.exec(this.replace(/\n/g, ' '));
if(match) {
return new Function(match[1].split(','), match[2]);
}
return null;
};
}
ตัวอย่างการใช้งาน:
var func = 'function (a, b) { return a + b; }'.parseFunction();
alert(func(3,4));
func = 'function (a, b) { alert("Hello from function initiated from string!"); }'.parseFunction();
func();
นี่คือ jsfiddle
JavaScript
Function
var name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'
ที่มา: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/
eval
var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'
sjsClass
https://github.com/reduardo7/sjsClass
Class.extend('newClassName', {
__constructor: function() {
// ...
}
});
var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
ในที่สุดเทคนิคนี้อาจเทียบเท่ากับวิธีการ eval แต่ฉันต้องการเพิ่มเพราะอาจมีประโยชน์สำหรับบางคน
var newCode = document.createElement("script");
newCode.text = "function newFun( a, b ) { return a + b; }";
document.body.appendChild( newCode );
นี่เป็นหน้าที่เหมือนกับการเพิ่มองค์ประกอบ <script> นี้ที่ส่วนท้ายของเอกสารของคุณเช่น:
...
<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>
</body>
</html>
ใช้new Function()
กับผลตอบแทนภายในและดำเนินการทันที
var s = `function test(){
alert(1);
}`;
var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()
ตัวอย่างที่มีอาร์กิวเมนต์แบบไดนามิก:
let args = {a:1, b:2}
, fnString = 'return a + b;';
let fn = Function.apply(Function, Object.keys(args).concat(fnString));
let result = fn.apply(fn, Object.keys(args).map(key=>args[key]))