머리말
ECMAScript에는 기능 객체를 생성하는 데 가장 일반적으로 사용되는 두 가지 방법, 즉 기능 표현식을 사용하거나 기능 선언을 사용합니다. 이와 관련하여 ECMAScript 사양은 함수 선언이 항상 식별자를 가지고 있어야한다는 것을 분명히합니다. 이는 우리가 함수 이름이라고 부르는 기능을 생략 할 수 있습니다. 이 둘의 차이점에 대한 자세한 소개를 살펴 보겠습니다.
기능 선언이란 무엇입니까?
함수 선언은 변수에 값을 할당하지 않고 명명 된 기능 변수를 정의 할 수 있습니다. 함수 선언은 비 기능 모듈에 중첩 될 수없는 독립적 인 구조입니다. 변수 선언과 비교할 수 있습니다. 변수 선언이 "var"로 시작 해야하는 것처럼 함수 선언은 "function"으로 시작해야합니다.
예를 들어
함수 바 () {return 3;}ECMA 5 (13.0) 정의 구문 :
function Identifier ( FormalParameterList[opt] ) { FunctionBody }
기능 이름은 자체 범위와 상위 범위 내에서 사용할 수 있습니다 (그렇지 않으면 함수를 사용할 수 없습니다).
함수 bar () {return 3;} bar () // 3bar // 함수함수 표현식이란 무엇입니까?
함수 표현식은 함수를 표현식 문의 일부로 정의합니다 (일반적으로 변수 할당). 함수 표현식으로 정의 된 함수는 명명되거나 익명으로 표시 될 수 있습니다. 함수 표현식은 "기능"으로 시작할 수 없습니다 (다음 자체 예제는 괄호로 둘러싸여 있어야합니다).
예를 들어
// 익명 함수 expressionVar a = function () {return 3;} // 이름이 forting expressionvar a = function 3;} // self vortion expression (function sayhello () {alert ( "hello!");}) ();ECMA 5 (13.0) 정의 구문 :
function Identifieropt ( FormalParameterList[opt] ) { FunctionBody }
(이 정의는 조건을 무시하기 때문에 불완전하다고 느낍니다. 주변 문장은 표현이며 "기능"으로 시작하지 않습니다).
함수 이름 (있는 경우)은 외부 범위 (함수 선언과 비교)를 사용할 수 없습니다.
그렇다면 함수 명령문이란 무엇입니까?
함수 명령문은 때때로 또 다른 기능 선언입니다. 그러나 Kangax는 Mozilla에서 함수 명령문은 함수 선언의 확장으로, 함수 선언문을 명세서를 사용할 수있는 어느 곳에서나 사용할 수 있다고 지적합니다. 그러나 기능 명세서는 현재 표준이 아니므로 제품 개발에 사용하는 것이 좋습니다.
작은 테스트부터 시작하겠습니다. 다음 상황에서 무엇이 나타날지 맞춰보세요?
Question 1:
함수 foo () {function bar () {return 3; } return bar (); 함수 bar () {return 8; }} alert (foo ());Question 2:
함수 foo () {var bar = function () {return 3; }; 리턴 바 (); var bar = function () {return 8; };} alert (foo ());질문 3 :
ALERT (foo ()); function foo () {var bar = function () {return 3; }; 리턴 바 (); var bar = function () {return 8; };}Question 4:
함수 foo () {return bar (); var bar = function () {return 3; }; var bar = function () {return 8; };} alert (foo ());답변이 8, 3, 3이 아니고 [유형 오류 : 막대가 함수가 아님]이면 계속 읽으십시오 ... (올바르게 대답하더라도 계속 읽어야합니다).
이제 이전 테스트를 설명해 봅시다.
질문 1은 함수 선언을 사용합니다.
잠깐만 요, 입는 게 뭐야?
다음은 Ben Cherry의 인용문입니다. "기능 선언 및 기능 변수는 일반적으로 JavaScript 통역사가 현재 범위의 상단으로 이동 ( '호이스트')."
함수 선언이 촉진되면 전체 기능 본문이 그에 따라 홍보되므로 질문 코드는 통역사가 설명한 후 다음과 같이 실행됩니다.
// ** 질문 1 ** function foo () {// 일단 함수 bar () {return 3; } // 재정의 it function bar () {return 8; } // reture return return bar (); // 8} alert (foo ());그러나 우리는 종종 반환 문 뒤의 코드가 실행할 수 없다고 들었습니다 ...
JavaScript를 실행하는 동안 두 가지 개념이 있습니다. 컨텍스트 (ECMA 5는이를 LexicalEnvironment, 변수 환경 및이 바인드 링) 및 프로세스 (순서대로 불리는 일련의 진술)로 나뉩니다. 프로그램이 실행 도메인에 들어가면 선언은 변수 환경을 유발합니다. 그것들은 진술과 다르며 (예 : 반환) 규칙을 실행하는 진술을 따르지 않습니다.
기능 표현이 촉진됩니까?
그것은 표현에 따라 다릅니다. 예를 들어, 질문 2의 첫 번째 표현 :
var bar = function () {return 3;};동일 부호의 왼쪽 (var bar)은 변수 선언입니다. 변수 선언이 촉진되지만 과제 표현은 그렇지 않습니다. 따라서 바가 승진하면 통역사는 다음과 같이 초기화됩니다 : var bar = undefined. 함수 정의 자체는 홍보되지 않습니다.
(ECMA 5 12.2 초기 지어가있는 변수는 변수가 생성 될 때가 아니라 variableStatement가 실행될 때 할당 표현에 의해 할당됩니다.)
따라서 질문 코드는 다음 순서로 실행됩니다.
// ** 질문에 대한 시뮬레이션 처리 시퀀스 2 ** 함수 foo () {// 각 함수 표현식에 대한 선언 var bar = undefined; var bar = 정의되지 않은; // 첫 번째 함수 표현식이 실행됩니다. bar = function () {return 3; }; // 첫 번째 함수에 의해 생성 된 함수 표현식은 호출되며 리턴 바 (); // 두 번째 함수 expressure} alert (foo ()); // 3당신은 이것이 설명 될 수 있다고 말할 수 있지만 질문 3에 대한 답은 잘못되었습니다. FireBug를 실행할 때 오류를보고하겠습니다.
HTML 파일에 코드를 저장하고 Firefox에서 실행해보십시오. 또는 IE8, Chrome 또는 Safari 콘솔에서 실행하십시오. 분명히, Firebug 콘솔은 "글로벌"범위에서 코드를 실행할 때 기능을 홍보하지 않습니다 (실제로는 글로벌이 아니라 고유 한 "Firebug"범위는 Firebug 콘솔에서 "this == Window"를 실행하려고 시도합니다).
질문 3과 질문 1은 비슷한 논리를 가지고 있습니다. 이번에는 FOO 기능이 촉진되었습니다.
질문 4는 매우 간단하고 기능 개선이 전혀 없습니다 ...
말할 수는 있지만, 개선이 전혀 없다면 타입 원자는 "함수가 아닌 막대"대신 "막대 정의되지"않습니다. 이 예에서는 실제로 기능 개선이 없지만 가변적 인 개선이 있습니다. 따라서 막대는 처음에 선언되지만 그 값은 정의되지 않습니다. 다른 코드는 순서대로 실행됩니다.
// ** 질문 4 ** function foo () {// 각 함수 표현식 var bar = undefined; var bar = 정의되지 않은; 리턴 바 (); // typeError : "bar not defined"// 기능 표현식에 도달하지 않음} alert (foo ());또 무엇에주의를 기울여야합니까?
공무원은 기능하지 않는 모듈에서 기능 선언의 사용을 금지합니다 (예 : IF). 그러나 모든 브라우저는이를 지원하지만 설명은 다릅니다.
예를 들어, 다음 코드 스 니펫은 함수 선언을 함수 명령문으로 해석하므로 (위 참조) Firefox 3.6에 오류가 발생하므로 X가 정의되지 않습니다. 그러나 IE8, Chrome 5 및 Safari 5에서는 함수 X가 반환됩니다 (표준 함수 선언과 동일).
함수 foo () {if (false) {function x () {}; } return x;} alert (foo ());함수 선언을 사용하여 혼란을 유발할 수 있으므로 장점이 있습니까?
함수 선언이 상당히 느슨하다고 말할 수 있습니다. 선언 전에 함수를 사용하려고하면 프로모션이 실제로 순서를 수정하여 기능을 올바르게 호출 할 수 있습니다. 그러나 이런 종류의 느슨 함은 엄격한 코딩에 도움이되지 않으며, 장기적인 관점에서 볼 때 사고를 예방하기보다는 홍보 할 가능성이 높습니다. 결국, 프로그래머가 특정 순서로 진술을 마련하는 이유가 있습니다.
그렇다면 기능 표현을 지원해야 할 다른 이유가 있습니까?
어떻게 생각하나요?
1) 함수 선언은 Java 스타일 메소드 선언을 모방하는 것처럼 느껴지지만 Java 메소드는 JavaScript와 다릅니다. JavaScript에서 함수는 값이있는 살아있는 대상입니다. Java 방법은 메타 데이터의 저장입니다. 다음 두 가지 코드가 함수를 정의하지만 함수 표현식 만 객체가 생성되는 것처럼 보입니다.
// 함수 선언 설립 추가 (a, b) {return a + b}; // function expressionvar add = function (a, b) {return a + b};2) 함수 표현식에는 더 많은 용도가 있습니다. 기능 선언은 고아에만 "진술"으로 만 존재할 수 있습니다. 현재 범위에서 객체 변수를 만드는 것입니다. 정의상 기능 표현은 큰 구조의 일부입니다. 익명 함수를 만들거나 프로토 타입에 함수를 추가하거나 다른 객체의 속성으로 기능을 사용하려면 기능 표현식을 사용할 수 있습니다. 카레 또는 작곡과 같은 고급 응용 프로그램을 사용할 때마다 새로운 기능을 만들 때 기능 표현식을 사용합니다. 기능 표현 및 기능 프로그래밍은 분리 할 수 없습니다.
// function expressionVar sayhello = alert.curry ( "hello!");
함수 표현식에 단점이 있습니까?
함수 표현식은 대부분의 기능을 익명으로 만듭니다. 예를 들어, 다음 함수는 익명입니다. 오늘날은 익명 기능에 대한 참조 일뿐입니다.
var today = function () {return new Date ()}이것이 문제가 될까요? 대부분의 경우가 아니라 Nick Fitzgerald가 지적했듯이 익명의 기능을 디버깅하는 것은 성가신 일 수 있습니다. 그는 NFES (Notional Function Expressions)를 작업 공간으로 사용하는 것이 좋습니다.
var today = function today () {return new Date ()}그러나 Asen Bozhilov가 말했듯이 (및 Kangax 문서) NFE는 IE9보다 올바르게 실행할 수 없습니다.
결론적으로
무작위로 배치 된 함수 선언은 오해의 소지가 없으며 거의 (있는 경우) 상황이 변수에 값을 할당하면 함수 선언을 대체 할 수 없습니다. 그러나 함수 선언이 필요한 경우 범위 상단에 올리면 혼란이 줄어들 수 있습니다. IF 문에 기능 선언을하지 마십시오.
너무 많이 말하면, 기능 선언은 자신의 상황에서 유용 할 수 있습니다. 아무것도 아니에요. 역할 교리는 위험하며 종종 코드가 덤불 주변에서 이길 수 있습니다. 더 중요한 것은 개념을 이해하여 자신의 상황에 따라 기능을 생성 할 방법을 결정할 수 있습니다. 위는이 기사의 전체 내용입니다. 이 기사가 이와 관련하여 모든 사람에게 도움이되기를 바랍니다.