eval(“1 2”),->
소스 코드에서 문자열을 동적으로 결정하는 것은 실제로 적용할 필요가 거의 없는 매우 강력한 언어 기능입니다. eval()을 사용하는 경우 실제로 사용해야 하는지 신중하게 고려해야 합니다.
1. eval()은 함수인가요 아니면 연산자인가요
eval()은 함수이지만 연산자로 취급되었습니다. . 초기 버전의 JavaScript 언어는 eval 함수를 정의했으며 최신 JavaScript 인터프리터는 광범위한 코드 분석 및 최적화를 수행합니다. eval의 문제는 일반적으로 동적 실행에 사용되는 코드를 분석할 수 없다는 것입니다. 즉, 함수가 eval을 호출하면 인터프리터가 함수를 더 이상 최적화할 수 없고 eval을 함수의 다른 부분으로 정의할 수 없다는 것입니다. 다른 이름(var f=eval;)을 지정할 수 있으면 인터프리터는 f()를 호출하는 함수를 안전하게 최적화할 수 없습니다. eval이 연산자이면 이러한 문제를 피할 수 있습니다.
2. 평가()
eval()에는 매개변수가 하나만 있습니다. 전달된 매개변수가 문자열이 아닌 경우 이 함수를 직접 반환합니다. 매개변수가 문자열이면 문자열을 JavaScript 코드로 컴파일하고 컴파일이 실패하면 구문 오류 예외가 발생합니다. 컴파일이 성공하면 이 코드 조각이 실행되고 문자열의 마지막 표현식이나 명령문의 값이 반환됩니다. 마지막 표현식이나 명령문에 값이 없으면 결국 undefound가 반환됩니다. 문자열에서 예외가 발생하면 이 예외는 호출을 eval()에 전달합니다.eval에서 가장 중요한 점은 호출되는 가변 범위 환경을 사용한다는 것입니다. 즉, 변수의 값을 조회하고 로컬 범위의 코드와 완전히 동일하게 새로운 변수와 함수를 정의합니다. 함수가 지역 변수 x를 정의한 다음 eval("x")를 호출하면 지역 변수의 값을 반환합니다. eval("x=1")을 호출하면 지역 변수의 값이 변경됩니다. 함수가 eval("var y=2;")을 호출하면 새 지역 변수 y를 선언합니다. 마찬가지로 함수는 다음 코드를 통해 지역 변수를 선언할 수 있습니다.
eval(“함수 f(){return x 1;}”);
물론 최상위 코드에서 eval이 호출되면 전역 변수와 전역 함수에 대해 작동합니다.
eval에 전달된 문자열은 문법적으로 일관성이 있어야 합니다. eval을 통해 함수에 임의의 코드 조각을 붙여넣을 수 없습니다. 예를 들어 eval("return;")은 return만 재생하기 때문에 의미가 없습니다. 실제로 eval 문자열이 실행될 때의 컨텍스트는 함수가 호출되는 컨텍스트와 동일하므로 함수의 일부로 실행될 수 없습니다. 문자열이 별도의 스크립트로 의미가 있는 경우 이를 매개변수로 eval에 전달하는 데 문제가 없습니다. 그렇지 않으면 eval에서 구문 오류 예외가 발생합니다.
3. 글로벌 평가()
eval()에는 레이아웃 변수를 변경하는 기능이 있는데 이는 JavaScript 최적화 프로그램에 큰 문제입니다. 그러나 임시방편으로 JavaScript 인터프리터는 eval을 호출하는 함수에 대해 많은 최적화를 수행하지 않습니다. 하지만 스크립트가 eval에 대한 별칭을 정의하고 이를 다른 이름으로 호출할 때 JavaScript 인터프리터는 어떻게 작동합니까? JavaScript 인터프리터 구현을 단순화하기 위해 ECMAScript3 표준에서는 인터프리터가 eval에 별칭을 할당할 수 없도록 규정하고 있습니다. eval 함수가 별칭을 통해 호출되면 EavlError 예외가 발생합니다.실제로 대부분의 구현에서는 이를 수행하지 않습니다. 별칭을 통해 호출되면 eval은 해당 문자열을 최상위 전역 코드로 실행합니다. 실행된 코드는 새로운 전역 변수와 전역 함수를 정의하거나 전역 변수에 값을 할당할 수 있지만 호출 함수에서 지역 변수를 사용하거나 수정할 수는 없습니다. 따라서 이는 함수 내의 코드 최적화에 영향을 미치지 않습니다.
ECMAScript5는 EavlError 사용에 반대하며 eval의 동작인 "direct eval"을 표준화합니다. 정규화되지 않은 "eval" 이름을 사용하여 eval() 함수를 직접 호출하는 경우 일반적으로 "direct eval"이라고 합니다. eval()이 직접 호출되면 항상 호출된 컨텍스트 범위 내에서 실행됩니다. 다른 간접 호출은 전역 개체를 컨텍스트 범위로 사용하며 지역 변수 및 함수를 읽거나 쓰거나 정의할 수 없습니다. 샘플 코드는 다음과 같습니다.