자바 스크립트를 사용하여 문자열에서 함수를 만드는 방법이 있습니까?


107

예를 들면 다음과 같습니다.

var s = "function test(){
  alert(1);
}";

var fnc = aMethod(s);

이것이 문자열이면 fnc라는 함수를 원합니다. 그리고 fnc();경고 화면이 나타납니다.

eval("alert(1);") 내 문제를 해결하지 못합니다.

답변:


73

문자열에서 함수를 만드는 4 가지 방법에 대한 jsperf 테스트를 추가했습니다.

  • Function 클래스와 함께 RegExp 사용

    var func = "function (a, b) { return a + b; }".parseFunction();

  • "return"과 함께 Function 클래스 사용

    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; };");

http://jsben.ch/D2xTG

2 개의 결과 샘플 : 여기에 이미지 설명 입력 여기에 이미지 설명 입력


@KthProg Chill down;). 항상 나쁜 것은 아닙니다. 이런 상황에서 jsperf가 현재 다운되었습니다. 다행히도 제가 Bulk에서 댓글을 받았을 때 다운되기 전에 결과 스크린 샷을 추가했습니다.
phnah

@KthProg FYI 이것은 중재 시스템에 의해 생성 된 미리 준비된 응답이었습니다. :) 대기열에 팝업되고 미리 결정된 문제가 있는지 확인합니다. 그것은 어렵고 빠른 규칙이 아니며 주석이 명령이 아닌 제안 형식임을 알 수 있습니다.
Dan Smith

174

문자열에서 함수를 만드는 더 좋은 방법은 다음을 사용하는 것입니다 Function.

var fn = Function("alert('hello there')");
fn();

이것은 현재 범위의 변수 (전역 적이 지 않은 경우)가 새로 생성 된 함수에 적용되지 않는다는 장점 / 단점을 가지고 있습니다.

인수 전달도 가능합니다.

var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'

5
동의합니다 Function. 로컬 스코프를 오염시키지 않기 eval때문에 엔진 최적화가 너무 어려워집니다. OP 예제를 사용하면 다음을 수행합니다.var fnc = Function('return '+s)();
CMS

나는 이것이 아마도 받아 들여진 대답이어야한다고 생각한다. eval ()보다 훨씬 안전합니다.
Bryan Rayner

내 친구 인 당신은 많은 찬성표를받을 자격이 있습니다. 이것은 이벤트 등에 할당 될 수있는 함수 객체를 생성하는 이점이 있습니다. 예 : element.onclick = Function ( "alert ( 'test');");
라이언 릭스

1
@RyanGriggs 귀하의 경우에는 "eval"기능이 필요하지 않으므로 element.onclick = function() { alert("test"); }.
Lekensteyn

1
내 예에서 당신이 맞습니다. 그러나 문자열에 저장된 임의의 함수를 할당하려면 방법이 완벽합니다. 이것이 제가 실제로하려는 것입니다. 문자열 변수에 여러 함수가 저장되어 있고 하나를 onclick 작업에 할당하고 싶습니다.
Ryan Griggs

38

당신은 꽤 가깝습니다.

//Create string representation of function
var s = "function test(){  alert(1); }";

//"Register" the function
eval(s);

//Call the function
test();

여기 에 작동하는 바이올린이 있습니다.


함수가 선언되었다는 것을 알았지 만 함수 이름을 호출 할 수는 없었습니다. 감사합니다.
ymutlu

4
필수 eval미래의 검색 결과에 표시하는 경고 : eval: 해커에 대한 허점을 열 수 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...을 하지만 당신은 그 위험을 알고 그들을 피할 수 있다면, 다음이에 좋은 간단한 방법입니다 문자열에서 함수를 작성

데이터베이스 레코드에서 왔기 때문에 함수 이름이 없다면 어떻게 될까요?
Marcel Djaman

13

예, 사용 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입니다


안녕하세요이 방법에 화살표 기능 지원을 지원하십시오.
sathish kumar

1
이 오류는 typescirpt "속성 'parseFunction'이 '문자열'유형에 존재하지 않습니다."에서 수신됩니다.
Cegone

11

동적 함수 이름 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'

6

이 기술은 궁극적으로 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>

3

new Function()내부에 리턴이있는를 사용하고 즉시 실행하십시오.

var s = `function test(){
  alert(1);
}`;

var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()


1

동적 인수가있는 예 :

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]))

감사. 매우 흥미로운
Дмитрий Васильев
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.