JavaScript에서 함수를 정의하는 방법에는 두 가지가 있습니다.
function ftn(){} // 第一种 var ftn = function(){} // 第二种
어떤 사람들은 이 두 가지 작성 방법이 완전히 동일하다고 말합니다. 그러나 파싱하기 전에 전자의 작성 방식은 파서에 의해 자동으로 코드의 헤드로 승격되는데, 이는 함수를 먼저 정의한 후 사용하는 원칙에 위배되므로, 다음과 같은 경우에는 후자의 작성 방식을 사용하는 것이 좋습니다. 기능을 정의합니다.
이 문장을 읽고 첫 느낌은 두 단어를 사용하면 완전히 동일하지만 분석에서는 차이가 있다는 것입니다. 그러나 "이전 작성 방식은 파서에 의해 자동으로 코드 헤드로 승격됩니다"라는 그의 설명은 나를 혼란스럽게 했습니다.
그래서 다음과 같은 첫 번째 테스트를 했습니다.
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; function ftn() { b(); alert('new'); } ftn();//浏览器报内存溢出 </script>
그런 다음 두 번째 테스트를 했습니다.
<script type="text/javascript"> var ftn = function() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } ftn();//old,new依次弹出 </script>
이에 대한 온라인 설명은 다음과 같습니다. 첫 번째 방법은 함수 ftn은 처음에 재정의되지 않고 그 안에서 실행됩니다. 두 번째 방법인 ftn=function()은 Function의 코드에서 실행되지 않으므로 여기서 다시 정의하는 것이 유효합니다.
명확하지 않은 경우 다음과 같이 테스트했습니다.
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; function ftn() { b(); alert('new'); } alert(b);//结果是重新定义的ftn内容 </script>
테스트 결과 ftn을 재정의하면 b의 내용도 변경되는 것으로 나타났습니다. 다음으로 두 가지 테스트를 더 수행했습니다.
<script type="text/javascript"> var ftn = function() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } alert(b);//结果是老的ftn内容 </script>
이것은 매우 흥미롭습니다. JavaScript에서는 기본 데이터 유형을 제외하고 다른 유형은 객체이며 해당 객체의 별칭은 주소입니다. 스택에서 후자의 테스트는 이 원리를 사용하여 분명히 이해할 수 있습니다. 그렇다면 이전 테스트 b가 ftn을 재정의하면서 변경된 이유는 무엇일까요?
새로운 설명이 있습니다. 맞는지 아닌지는 모르겠습니다. 모든 JavaScript 책에 언급될 것입니다. JavaScript에는 나중에 정의된 동일한 이름의 함수가 덮어쓰여집니다. 이전 함수, var b = ftn; 이 문장은 b 및 ftn의 참조를 동일한 힙의 메모리에 지정합니다. 함수 ftn(){}을 재정의한 후 새 함수 객체는 이전 객체와 b가 참조하는 힙을 덮어씁니다. ftn 주소 공간이 변경되지 않은 경우 다음과 같이 작성하는 것이 합리적입니다.
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } alert(b);//老的ftn alert(ftn);//新的ftn ftn();//old ,new </script>
이런 방식으로 스택에 있는 새 ftn의 주소가 변경되어 다음을 가리킵니다. 새 함수 개체의 정의와 원본 함수는 덮어쓰지 않고 계속 저장되므로 b는 여전히 이전 ftn에서 참조하는 주소입니다.
방금 JavaScript의 함수 이해에 대한 기사를 작성했습니다. 기사의 내용을 되돌아보면 테스트 결과에 대한 이해에 여전히 문제가 있다는 느낌이 듭니다. 컴파일과 실행부터 시작해보세요. JavaScript는 코드가 실행될 때 코드를 컴파일하므로 var에 정의된 유형이 가변적일 수 있습니다. 우리가 캡슐화하는 개체에는 속성과 메서드가 추가되는 경우가 많기 때문에 이러한 방식으로 내 제목으로 인해 발생하는 문제를 이해할 수 있습니다. , 정의와 같은 변수 var obj = new Object()는 JavaScript에서 사전 컴파일이라고 하는 매우 초기 프로세스만 수행합니다. 이 사전 컴파일 기능은 매우 약해서 실행에 영향을 주지 않고 마음대로 변경할 수 있습니다. 객체가 호출되면 JavaScript 인터프리터가 코드를 컴파일한 다음 실행합니다. 이는 Java와는 매우 다르며, Java는 코드를 먼저 컴파일한 다음 호출할 때 이를 실행합니다. 대부분의 스크립팅 언어는 빠르지 않습니다. 그러나 fonction ftn(){}과 같은 함수를 정의하면 코드가 컴파일됩니다. 즉, 이 작성 방법은 Java 함수 정의와 매우 유사합니다. 이것은 나의 새로운 해석이고, 나는 이 설명이 더 타당하다고 생각한다.
JavaScript의 "컴파일"은 코드 오류가 있는지만 확인하고 코드를 실행하지는 않습니다. 함수에 무엇이든 작성하여 테스트해 볼 수 있습니다. 미리 로드하고 먼저 기능을 수행한 다음 var를 수행합니다. 위 코드에서는 데모1과 데모3의 소스 코드 순서가 function - var - function 입니다. preloading 후의 순서는 function - function - var 입니다. 🎜 >
<script type="text/javascript"> //demo1 function ftn() { alert('old'); } function ftn() { b(); alert('new'); } var b = ftn; ftn();//浏览器报内存溢出 </script>프리로드는 여기까지입니다.
<script type="text/javascript"> //demo3 function ftn() { alert('old'); } function ftn() { b(); alert('new'); } var b = ftn; alert(b);//结果是重新定义的ftn内容 </script>