eval ()과 new Function ()은 같은 것입니까?


92

이 두 기능이이면에서 동일한 작업을 수행합니까? (단일 명령문 함수)

var evaluate = function(string) {
    return eval('(' + string + ')');
}

var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));

3
사실 이것은 jQuery 1.7.2 라인 573에서 사용됩니다. "일부 보안 검사"를 사용하더라도
— PicoCreator

2
new이 토론에서 왜 고려됩니까? Function암시 적으로 function object. 제외 new해도 코드는 전혀 변경되지 않습니다. 다음은이를 보여주는 jsfiddle입니다. jsfiddle.net/PcfG8
— Travis J

답변:


117

아니요, 동일 하지 않습니다 .

  • eval() 현재 실행 범위 내에서 문자열을 JavaScript 표현식으로 평가하고 로컬 변수에 액세스 할 수 있습니다.
  • new Function()문자열에 저장된 JavaScript 코드를 함수 객체로 구문 분석 한 다음 호출 할 수 있습니다. 코드가 별도의 범위에서 실행되기 때문에 지역 변수에 액세스 할 수 없습니다.

이 코드를 고려하십시오.

function test1() {
    var a = 11;
    eval('(a = 22)');
    alert(a);            // alerts 22
}

사용 된 경우 new Function('return (a = 22);')()지역 변수 a는 해당 값을 유지합니다. 그럼에도 불구하고 Douglas Crockford와 같은 일부 JavaScript 프로그래머 는 절대적으로 필요한 경우가 아니면 둘 다 사용해서는 안된다고 생각하며 Function신뢰할 수없는 데이터 에서 생성자를 평가 / 사용하는 것은 안전하지 않으며 현명하지 않습니다.


11
"사용해서는 안된다"는 말은 매우 광범위합니다. 어떻습니까, 입력 중 하나가 통제를 벗어 났을 때 절대 사용해서는 안됩니다. 그렇다고해서 JSON 구문 분석을 제외하고는 사용할 필요가 없었습니다. 그러나 여기에서 유효한 사용처럼 보이는 질문에 대답했습니다. 관리자가 최종 사용자가 사용할 수있는 템플릿 기능을 생성하도록 허용하는 것과 같은 작업이 포함되었습니다. 이 경우, 입력은 관리자에 의해 생성되므로 허용되었다
— 후안 멘데스

3
@Juan : Crockford의 요점은 eval이 자주 오용된다는 것입니다 (귀하의 관점에 따라 다름). 따라서 "모범 사례"JavaScript에서 제외되어야합니다. 그러나 입력이 처음 올바르게 검증 될 때 JSON 또는 산술 표현식 구문 분석과 같은 용도에 유용하다는 데 동의합니다. Crockford조차도 JSON 라이브러리 json2.js에서이를 사용합니다.
— PleaseStand 2011 년

그렇다면 이것이 완전히 새로운 실행 컨텍스트 new Function(code)와 동일 eval('(function(){'+code+'})()')하거나 완전히 새로운 것임을 의미 합니까?
— George Mauer 2012

5
@GeorgeMauer : eval('(function(){'+code+'})')함수 객체를 반환하는 을 의미한다고 생각 합니다. MDN에 따르면 "Function 생성자로 생성 된 함수는 생성 컨텍스트에 대한 클로저를 생성하지 않습니다. 항상 창 컨텍스트에서 실행됩니다 (함수 본문이"use strict "로 시작하지 않는 한, 컨텍스트가 정의되지 않은 경우)) . "
— PleaseStand jul.

6

아니.

업데이트 에서 동일한 결과를 호출 evaluate하고 func생성합니다. 그러나 그들은 "뒤에서 똑같은 일을하는 것"이 ​​가장 확실합니다. 이 func함수는 새 함수를 생성하지만 즉시 실행하는 반면, evaluate함수는 그 자리에서 코드를 실행합니다.

원래 질문에서 :

var evaluate = function(string) {
    return eval(string);
}
var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

이는 매우 다른 결과를 제공합니다.

evaluate('0) + (4');
func('0) + (4');

어쨌든 둘 다 가장 예외적 인 경우를 제외하고 모두 나쁜 습관입니다.
— palswim 2011 년

8
당신은 그의 구현에 따라 당신의 모범을 퍼뜨 렸습니다. 그가 평가를 구현했다면 return eval('(' + string + ')');그들은 동일한 결과를 산출 할 것입니다.
— Juan Mendes 2011 년

@Juan 나는 생각하지 않았지만 그래. 질문 수정
— qwertymk 2011 년

6

new Function재사용 할 수있는 함수를 만듭니다. eval주어진 문자열을 실행하고 마지막 문의 결과를 반환합니다. 평가를 에뮬레이트하기 위해 Function을 사용하는 래퍼 함수를 ​​만들려고 시도했을 때 질문이 잘못되었습니다.

그들이 커튼 뒤에서 몇 가지 코드를 공유한다는 것이 사실입니까? 예, 가능성이 높습니다. 정확히 같은 코드? 아니, 확실히.

재미를 위해 eval을 사용하여 함수를 만드는 내 자신의 불완전한 구현이 있습니다. 그것이 차이에 대해 약간의 빛을 비추 길 바랍니다!

function makeFunction() {
  var params = [];
  for (var i = 0; i < arguments.length -  1; i++) {
    params.push(arguments[i]);
  }
  var code = arguments[arguments.length -  1];


 // Creates the anonymous function to be returned
 // The following line doesn't work in IE
 // return eval('(function (' + params.join(',')+ '){' + code + '})');
 // This does though
 return eval('[function (' + params.join(',')+ '){' + code + '}][0]');
}

이 함수와 새 함수의 가장 큰 차이점은 함수가 어휘 적으로 범위가 지정되지 않는다는 것입니다. 그래서 그것은 클로저 변수에 접근 할 수없고 내 것입니다.


arguments.slice()for 루프 대신 사용 하지 않는 이유 는 무엇입니까? 또는 인수가 참 배열이 아닌 경우 [].slice.call(arguments, 1).
— Xeoncross

3

여기 예제에서 사용 된 몇 가지 구문과 그 의미를 지적하고 싶습니다.

 var func = function(string) {
     return (new Function( 'return (' + string + ')' )());
 }

Function (...) () 끝에 "()"가 있습니다. 이 구문은 func가 새 함수를 실행하고 문자열을 반환하는 함수가 아니라 다음을 사용하는 경우 문자열을 반환하도록합니다.

 var func = function(string) {
     return (new Function( 'return (' + string + ')' ));
 }

이제 func는 문자열을 반환하는 함수를 반환합니다.


2

당신이 의미한다면, 그것은 같은 결과를 산출 할 것인가, 그렇다면 그렇다 ... 그러나 단지 평가 (즉, "이 JavaScript 문자열을 평가하라")는 훨씬 더 간단 할 것이다.

아래 편집 :

마치 ...이 두 가지 수학 문제가 동일합니까?

1 + 1

1 + 1 + 1-1 + 1-1 * 1/1


둘 다 문자열을 다시 구문 분석합니까?
— qwertymk 2011 년

둘 다 문자열을 구문 분석합니다 (코드 예제에서). "재분석"이 의미하는 바를 모릅니다.
— Timothy Khouri 2011 년

1
나는 둘 다 어느 시점에서 문자열을 구문 분석 (평가)한다고 확신하지만 Function객체는 아마도 eval함수를 호출 할 때 개인 멤버 변수에 문자열을 저장합니다 .
— palswim 2011 년

1

이 예에서 결과는 동일합니다. 둘 다 전달한 표현식을 실행합니다. 이것이 그들을 매우 위험하게 만드는 것입니다.

그러나 그들은 scense 뒤에 다른 일을합니다. 포함하는 하나는 new Function(), 뒤에 - 더 - 장면, 함수가 호출 될 때 실행되는 사용자가 제공 한 코드에서 익명 함수를 만듭니다.

전달하는 JavaScript는 익명 함수를 호출 할 때까지 기술적으로 실행되지 않습니다. 이는 eval()코드를 즉시 실행하고이를 기반으로 함수를 생성하지 않는 것과는 대조적 입니다.


좀 더 설명해 주 시겠어요? 둘 다 return 문에서 실행되지 않습니까? Function () 하나가 eval 이외의 다른 스택 호출 수준을 사용합니까?
— qwertymk 2011 년

Does the Function() one use another stack call level than eval?: eval()입력에서 함수를 생성하지 않고 실행 하기 때문에 그렇게 가정 합니다. new Function()새 함수를 만든 다음 호출합니다.
— Chris Laplante 2011 년

@SimpleCoder : Function ()은 호출 스택에 아무것도 추가하지 않습니다. 결과 함수를 호출하는 경우에만. eval은 똑같은 작업을 수행합니다 (질문의 맥락에서 적용되는 경우)
— Juan Mendes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.