기능
기능 형식
함수 getProtoTynames (o,/*옵션*/ a) {a = a || []; for (var p in o) {a.push (p);} return a;}방문객
func.caller는 함수 발신자를 반환합니다
function callfunc () {if (callfunc.caller) {alert (callfunc.caller.toString ());} else {alert ( "no function call");}} 함수 handleCaller () {callfunc ();} handlecaller (); // return handlercallfunc (); // return, null function ";칼리
익명 방법 재귀 호출
alert ((함수 (x) {if (x <=) return; return x * arguments.callee (x -);} ()); //범위
모두가 그 범위에 익숙합니다. 오늘은 폐쇄 문제에 대해 이야기하고 폐쇄 문제를 철저히 이해할 것입니다.
<cript> var global = "Global Scope"; // 이것은 글로벌 스코프 함수 스코프 () {var scope = "로컬 스코프"입니다. // 이것은 로컬 스코프 리턴 스코프입니다. // 반환 된 스코프는 로컬 변수입니다} </script>1. : 정의 된 글로벌 변수는 함수 내부에서도 액세스 할 수 있습니다 . 정의 된 로컬 변수 및 글로벌 변수 이름이 동일하면 로컬 변수는 글로벌 변수를 숨기고 글로벌 변수의 값을 파괴하지 않습니다.
var scope = "global scope"; function f () {var scope = "local scope"; return scope;} alert (f ()); // local scopealert (scope); // global scope;위의 내용은 실제로 이해하기 쉽습니다.
2. Global 변수는 VAR없이 선언 할 수 있지만 로컬 변수는 var로 선언해야합니다. 로컬 변수가 VAR 선언을 사용하지 않으면 컴파일러가 기본적으로이를 전역 변수로 기본값으로합니다.
<span style = "line-height :; font-family : verdana, arial, helvetica, sans-serif; font-size : px; 배경색 : rgb (,,);"> </span> scope = "Global scope"; function f () {spope = "local scope"; return scope (f (f ()); // local scope ();그러나 글로벌 변수는 VAR 선언을 사용하지 않으며 비 스트릭 모드에서만 사용할 수 있습니다. 엄격한 모드를 사용하면 오류 가보고됩니다.
<cript> "strict 사용"; Scope = "Global Scope"; 함수 f () {scope = "local scope"; return scope;} alert (f ()); // local scopealert (scope); // local scope </script>따라서 불필요한 문제를 피할 수 있으므로 변수를 선언 할 때 VAR을 생략하지 않는 것이 좋습니다.
3. 미리 선언해도 괜찮습니다 . 미리 무엇이 있습니까?
<cript> "strict 사용"; 스코프; console.log (scope); var scope = "global scope"; console.log (scope); </script>
이것은 정의되지 않은 최초의 인쇄로 볼 수 있습니다. 예, 아직 값이 할당되지 않았습니다. 다음 과제는 글로벌 범위를 결정할 수 있습니다.
이것은 잘못이 아니지만 왜 이런 일이 일어나고 있습니까? 변수를 사용하기 전에 정의해서는 안됩니까?
여기서는 스코프 체인에 대해 알려 드리겠습니다. JavaScript는 어휘 스코프 언어입니다.
1. 스코프 체인은 객체 또는 링크 된 목록입니다. 이 코드 세트는이 코드의 "범위"로 변수를 정의합니다. JavaScript가 변수 범위를 찾아야 할 때 체인의 첫 번째 객체에서 개발 및 검색됩니다. 첫 번째 객체가 범위 인 경우이 객체의 값이 직접 반환됩니다. 존재하지 않으면 두 번째 객체가 발견 될 때까지 계속 검색됩니다. 범위 체인에서 변수가 발견되지 않으면 오류가 발생합니다.
이 함수 체인을 다음과 같이 표현할 수 있습니다. 스코프-> 창 (글로벌 개체)을 찾으면 범위가 정의됩니다. 그러나 할당 작업은 수행되지 않았으며, 할당 작업은 나중에 수행되었으므로 현재 값은 정의되지 않습니다.
4. 이것은 더 혼란 스럽습니다. 인쇄 된 값은 무엇입니까?
<cript> "strict 사용"; var scope = "global scope"; function f () {console.log (scope); var scope = "local scope"; console.log (scope);} f (); </script>이 코드를 참조하십시오 : 부주의 한 경우, 당신은 잘못된 대답을 쓸 수 있습니다.
1. Gobal 범위
2. 로컬 범위
분석 : 글로벌 변수를 선언합니다. 기능 본문에서 첫 번째는 글로벌 변수를 나타내므로 글로벌이 인쇄되고 두 번째는 전역 범위를 다루는 로컬 변수를 정의하므로 로컬 범위가 인쇄됩니다.
이러한 분석은 C# Java에서 완전히 정확합니다. 그러나 여기의 분석은 실제로 잘못되었습니다.
이것은이 문제 전에 먼저 질문을 보자.
이 문장은 매우 중요합니다. 글로벌 변수는 항상 프로그램에 정의됩니다. 로컬 변수는 항상 기능의 본문 내에서 정의됩니다.
높은 수준의 언어로 작업하는 경우 범위 정의에 약간의 부적합한 JavaScript에 노출됩니다. 나는 똑같다. 예를 살펴 보겠습니다.
<cript> var g = "global scope"; function f () {for (var i =; i <; i ++) {for (var j =; j <; j ++) {;} console.log (j);} console.log (i);} console.log (g); f (); </script>인쇄 결과는 무엇입니까?
{}는 명령문 블록을 나타내고 명령문 블록이 동일한 블록의 범위에 있으므로 J 및 I 값이 메모리에서 해제되었다고 추측 할 수 있으므로 결과는 정의되지 않아야합니다.
실제 결과는 당신을 실망시킬 수 있습니다.
왜 이런 일이 일어 났습니까? 내 표현은 당신처럼 시작되었습니다.
내가 지금 기억하도록 요청한 문장을 확인하십시오. . . 글로벌 변수는 항상 프로그램에서 정의됩니다. 로컬 변수는 항상 기능의 본문 내에서 정의됩니다.
정확하게 말하면, 함수의 매개 변수는 또한 로컬 변수의 범주에 속합니다. 이 문장도 매우 중요합니다! ! !
이 문장은 대략 함수 내부에 정의 된 변수가 전체 함수 내에서 유효하다는 것을 의미합니다. 따라서 결과는 이해하기 어렵지 않습니다. 우리의 질문을 되돌아 보면 이해합니까?
행동 체인에는 다음과 같은 정의가 있습니다.
1. 액션 체인은 글로벌 객체로 구성됩니다.
2. 둥지가 포함되지 않은 기능 본문에는 액션 체인에 두 개의 물체가 있습니다. 첫 번째 객체는 함수 매개 변수와 로컬 변수를 정의하고 두 번째 객체는 전역 객체입니다.
3. 중첩 된 기능 본체에는 액션 체인에 최소 3 개의 물체가 있습니다.
함수가 정의되면 스코프 체인이 저장됩니다.
이 함수가 호출되면 로컬 변수를 저장하는 새로운 객체를 생성 하고이 객체를 저장된 동작 체인에 추가합니다. 동시에 함수 호출을 나타내는 새로운 장기 기능 체인을 만듭니다.
중첩 함수의 경우 외부 함수가 호출되면 내부 기능이 다시 재정의됩니다. 외부 기능을 호출 할 때마다 액션 체인이 다릅니다. 내부 기능은 정의 될 때마다 미묘한 차이가 있습니다. 외부 함수가 호출 될 때마다 내부 함수의 코드는 동일하며 관련 코드의 범위도 다릅니다.
폐쇄
오랫동안 그렇게 한 후 마침내 그것에 대해 이야기했지만 이전에 범위를 분석해 봅시다.
<cript> var nameg = "global"var g = function f () {console.log (name); function demo () {console.log ( "demo =" + name);} var name = ""; nameg);} demo (); demo (); demo ();}; g (); </script>우리는 액션 체인에 따라 분석합니다.
demo0, demo0 () -> 이름 찾기 이름을 찾으십시오 -> f (), return을 찾으십시오
demo1, demo1 ()-> 찾기 이름, 찾기, 반환을 호출하십시오
demo2, demo2 () -> nameg를 찾을 수 없음 -> f ()를 찾으려면 nameg를 찾으려면 -> nameg, return을 찾을 수 없습니다.
이 예를보십시오 :
<cript> function f () {var count =; return {counter : function () {return count ++;}, reture () {return count =;}}} var d = f (); var c = f (); console.log ( "D First Call :"+ d.counter ()); // console.log ( "c c.counter ("); ") 첫 번째 전화 : "+ c.counter ()); // </script>이 예에서 볼 수 있듯이 카운팅 및 제로 작동 작업을 수행했습니다.
f의 두 가지 객체 인스턴스는 각각 고유 한 스코프 체인을 사용하여 값이 서로 영향을 미치지 않습니다. C를 두 번째로 호출하면 C 객체가 파괴되지 않기 때문에 카운트 값이 저장됩니다. 이 예를 이해 한 후에 만 다음 예제는 이해하기가 더 쉽습니다.
이 과정에 대해 모든 사람이 매우 명확해야합니다. 이제 폐쇄 문제를 살펴 보겠습니다. 4 개의 버튼을 설정하고 각 버튼을 클릭하여 응답 이름을 반환합니다.
<body> <cript> function btninit () {for (var i =; i <; i ++) {var btn = document.getElementById ( "btn" + i); btn.addeventListener ( "click", function () {alert ( "btn" + i);}} windows = btnit; id = "btn"> btn </button> <button id = "btn"> btn </button> <button id = "btn"> btn </button> <button id = "btn"> btn </div> </body>실행하려면 클릭하지만 결과는 모두 BTN5입니다.
우리는 지금 분석에 앉았습니다. 먼저 익명 함수를 호출해야합니다 -> 찾을 수 없음 -> btninit ()를 찾아야합니다. 일어나십시오. 우리는 기능 호출 만 릴리스되고 i in for는 항상 볼 수 있으므로 마지막 I 값이 유지됩니다. 그래서 그것을 해결하는 방법.
I 값이 항상 함수에서 볼 수있는 문제를 해결하려면 기능의 중첩을 사용하고 I 값을 전달해야합니다.
function btninit () {for (var i =; i <; i ++) {(function (data_i) {var btn = document.getElementById ( "btn" + data_i); btn.addeventListener ( "click", function () {alert ( "btn" + data_i);} (i));})수정 된 코드를보고 먼저 첫 번째를 실행하고 개체를 만듭니다. 먼저 익명 함수 -> data_i를 실행하지만 찾을 수 없지만 -> function (data_i)을 실행 한 다음 다시 실행하여 개체를 만듭니다. 폐쇄 규칙은 서로 영향을 미치지 않는다고 말합니다. 따라서 올바른 결과를 얻을 수 있습니다.
위의 것은 편집자가 소개하는 JavaScript 필수 알고 있어야합니다 (9) 기능입니다. 폐쇄 문제에 대한 관련 지식에 대해 말하면, 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!