예를 들어 코드 블록
if(true) {
int i = 100;
}
print(i); //오류, 변수 i가 선언되지 않았습니다.
위의 예와 같이 코드 외부의 함수 블록은 i 변수에 액세스할 수 없습니다.
하지만 자바스크립트에서는 상황이 완전히 다릅니다.
if (true) {
var i = 100 ;
}
alert(i); //상자를 띄우고 100을 표시합니다.
많은 현대 언어에서는 변수 선언을 최대한 늦게 권장하지만 Javascript에서는 이것은 최악의 제안입니다. 블록 수준 범위가 부족하므로 함수 본문 상단에 함수에서 사용할 수 있는 모든 변수를 선언하는 것이 가장 좋습니다.
클로저 기능:
블록 수준 범위가 없어도 함수 범위는 여전히 존재합니다.
이런 종류의 범위의 한 가지 장점은 내부 함수가 자신이 정의된 외부 함수의 매개변수와 변수에 액세스할 수 있다는 것입니다(this 및 인수 제외).
이 기능을 이용하면 이런 코드를 디자인할 수 있습니다.
varbankAccount = function() {
var value = 0;
return {
예금: 함수(inc) {
value = inc;
},
getValue: 함수(){
반환 값 ;
}
}
}
var myAccount =bankAccount(); //새 은행 계좌 개설
myAccount.deposit(1000) //입금 yuan
alert(myAccount.getValue()); //should Alert(1000);
valuebankAccount 함수에 있으므로 외부에서 직접 조작할 수 없습니다. world이며,bankAccount를 통해 전달되어야 합니다. 이 함수는 작업을 수행하기 위해 반환하는 개체를 제공하며 이러한 방식으로 C# 및 Java의 개인 필드가 구현됩니다.
전역 변수가 전역 공간을 오염시키는 것을 줄입니다. 함수의 범위를 사용하면 js 라이브러리를 작성할 때 다른 라이브러리와의 충돌을 줄일 수 있습니다.
(function () {
var hello = ' Hello World.';
})();
alert(hello); //오류: hello no 존재합니다.
여기 구문이 조금 이상합니다. 주요 아이디어는 익명 메서드를 정의하고 즉시 실행하는 것입니다. 함수 시작 부분의 리터럴은 함수 정의로 해석되므로 이를 둘러싸기 위해 한 쌍의 괄호를 추가한 다음 함수가 호출됨을 나타내기 위해 한 쌍의 괄호를 사용합니다. 외부 경고는 함수 내부에 정의된 hello에 액세스할 수 없습니다.
트랩 1: var의 트랩
"전역 공간을 오염시키는 전역 변수의 속도를 늦추는 것"의 예가
(function () {
hello = 'Hello World.'; //remove var
})();
alert(hello); //alert ('Hello World.');
hello 변수가 var로 명시적으로 선언되지 않으면 hello가 전역 변수가 됩니다. ! !
이 기능을 이용하여 외부 인터페이스를 제공할 수는 있지만 권장하지는 않습니다.
(function () {
var hello = ' Hello World.';
sayHello = function () { //이런 방식으로 인터페이스를 제공하는 것은 매우 불분명해 보입니다.
alert(hello)}
})( ;
(함수(창) {
var hello = 'Hello World.';
window.$ = {
sayHello: 함수() {
alert(hello );
코드 복사
코드는 다음과 같습니다.
var obj = (함수 ( ) {
var hello = 'Hello World.';
return {
sayHello: function () {
alert(hello)}
}) ();
obj.sayHello()
트랩 2: 클로저 트랩
(function () { //함수 a
var arr = [];
var i = 0;
var j;
for ( ; i < 3; i ) {
arr.push(function () { //함수 b
alert(i * 10);
})
}
for (j in arr ) {
arr[j]();
}
})();
함수 배열 arr의 각 함수가 실행된 후 0, 10,20이 팝업되지만 그렇지 않은 것으로 나타났습니다. 결과는 30,30,30이 나타납니다.
함수 b는 i의 현재 값에 액세스하지 않고 변수 i에 직접 액세스합니다(항상 i의 최신 값을 가져오는 데 사용됨).
이유는 함수 b는 함수 a의 내부 함수이고 변수 i는 함수 b에 표시되며 함수 b는 매번 i에서 최신 값을 가져오기 때문입니다.
이번으로 변경되었습니다:
( function () { //function a
var arr = [];
var i = 0;
var j;
for ( ; i < 3; i ) {
arr.push((function (anotherI) { //함수 m
return function () { //함수 b
alert(anotherI * 10);
}
})(i) ); // 여기 있습니다 (function b(anotherI) {})(i)
}
for (j in arr) {
arr[j](); >}
})();
이 실행 후 마침내 0,10,20이 나타났습니다. 왜 이런가요?
함수 b는 변수 i에 직접 접근하는 대신 anotherI(당시 i의 값)에 접근한다.
arr.push 이전마다 새로운 익명 함수 m이 정의됩니다. 이 예에서는 세 개의 익명 함수 m0, m1 및 m2가 호출될 때마다 otherI가 현재 i의 값을 가져옵니다. 각 m 함수는 실행 후 b 함수를 반환합니다. b0은 m0에 있고, b1은 m1에 있고, b2는 m2에 있습니다. b0는 m0(0)의 다른 I에만 액세스할 수 있지만 m0과 m1은 서로 다른 함수이기 때문에 b0은 m1의 다른 I에 액세스할 수 없습니다.