(function() {})()jQuery에 특화된 사촌 (function($) {})(jQuery)은 자바 스크립트 코드에서 항상 팝업됩니다.
이러한 구성은 어떻게 작동하며 어떤 문제를 해결합니까?
감사의 예
(function() {})()jQuery에 특화된 사촌 (function($) {})(jQuery)은 자바 스크립트 코드에서 항상 팝업됩니다.
이러한 구성은 어떻게 작동하며 어떤 문제를 해결합니까?
감사의 예
jQuery가 논쟁으로 제공 하는지를 말하지 않습니다 .
답변:
JavaScript 프레임 워크의 인기가 높아짐에 따라이 $기호는 다양한 경우에 사용되었습니다. 따라서 가능한 충돌을 줄이기 위해 다음 구성을 사용할 수 있습니다.
(function ($){
// Your code using $ here.
})(jQuery);
특히, 이것은 주 jQuery 객체를 매개 변수로 전달하는 즉시 실행되는 익명 함수 선언입니다 . 해당 함수 내 에서 다른 프레임 워크가 범위에 있는지 걱정하지 않고 해당 개체를 참조하는 데 사용할 수 있습니다 .$
이것은 변수 범위를 제한하는 데 사용되는 기술입니다. 변수가 전역 네임 스페이스를 오염시키는 것을 방지하는 유일한 방법입니다.
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) 익명 함수를 정의하고 바로 실행합니다.
2) 일반적으로 원치 않는 코드로 전역 네임 스페이스를 오염시키지 않도록 수행됩니다.
3) 당신은 그것으로부터 몇 가지 메소드를 노출해야합니다. 내부 선언은 "비공개"입니다. 예를 들면 :
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
또는, 또는 :
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
요점은 여러 가지 방법으로 사용할 수 있지만 결과는 동일하다는 것입니다.
즉시 호출되는 익명 함수입니다. 먼저 함수를 만든 다음 호출하면 동일한 효과를 얻을 수 있습니다.
(function(){ ... })();
다음과 같이 작동합니다.
temp = function(){ ... };
temp();
명명 된 함수를 사용하여 동일한 작업을 수행 할 수도 있습니다.
function temp() { ... }
temp();
jQuery 특정이라고 부르는 코드는 jQuery 객체를 사용한다는 의미에서만 가능합니다. 즉시 호출되는 매개 변수가있는 익명 함수입니다.
두 단계로 동일한 작업을 수행 할 수 있으며 원하는 매개 변수로 수행 할 수 있습니다.
temp = function(answer){ ... };
temp(42);
이것이 해결하는 문제는 함수의 코드에 대한 클로즈를 생성한다는 것입니다. 전역 네임 스페이스를 오염시키지 않고 변수를 선언 할 수 있으므로 한 스크립트를 다른 스크립트와 함께 사용할 때 충돌 위험을 줄일 수 있습니다.
jQuery의 특정 경우에는 이름 $를 jQuery의 별칭으로 선언하지 않는 호환성 모드에서 사용합니다. jQuery 객체를 클로저로 보내고 매개 변수 이름을 $로 지정하면 호환성 모드없이 동일한 구문을 사용할 수 있습니다.
여기 에서 첫 번째 구성이 변수에 대한 범위를 제공한다고 설명 합니다.
변수는 자바 스크립트의 함수 수준에서 범위가 지정됩니다. 이것은 변수가 블록으로 범위가 지정된 C # 또는 Java와 같은 언어에서 익숙한 것과 다릅니다. 이것이 의미하는 바는 루프 또는 if 문 내에서 변수를 선언하면 전체 함수에서 사용할 수 있다는 것입니다.
함수 내에서 변수의 범위를 명시 적으로 지정해야하는 경우 익명 함수를 사용하여이를 수행 할 수 있습니다. 실제로 익명 함수를 만든 다음 바로 실행할 수 있으며 내부의 모든 변수는 익명 함수로 범위가 지정됩니다.
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
이를 수행하는 또 다른 이유 $는 사용 중인 프레임 워크의 연산자에 대한 혼란을 제거하는 것 입니다. 예를 들어 jQuery를 강제하려면 다음을 수행하십시오.
;(function($){
... your jQuery code here...
})(jQuery);
$연산자를 매개 변수로 전달하고 jQuery에서 호출하면 $다른 프레임 워크가로드 된 경우에도 함수 내의 연산자가 jQuery에 잠 깁니다.
이 구조의 또 다른 용도는 클로저에 사용될 지역 변수의 값을 "캡처"하는 것입니다. 예를 들면 :
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
위의 코드는 세 개의 버튼이 모두 "3"으로 팝업되도록합니다. 반면에 :
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
이렇게하면 예상대로 세 개의 버튼이 "0", "1", "2"로 표시됩니다.
그 이유는 클로저 가 해당 변수의 현재 값을 보유하는 둘러싸는 스택 프레임에 대한 참조를 유지하기 때문 입니다. 클로저가 실행되기 전에 이러한 변수가 변경되면 클로저는 클로저가 생성 된 시점의 값이 아닌 최신 값만 볼 수 있습니다. 위의 두 번째 예에서와 같이 다른 함수 안에 클로저 생성을 래핑하면 변수의 현재 값 i이 익명 함수의 스택 프레임에 저장됩니다.
이것은 폐쇄 로 간주됩니다 . 포함 된 코드가 자체 어휘 범위 내에서 실행됨을 의미합니다. 즉, 새 변수와 함수를 정의 할 수 있으며 클로저 외부의 코드에서 사용되는 네임 스페이스와 충돌하지 않습니다.
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
이렇게하면 세 개의 팝업이 생성 i되어 클로저의가 같은 이름의 기존 변수를 변경하지 않음을 보여줍니다 .
그들은 종종 jQuery 플러그인에서 사용됩니다. 에 설명 된대로jQuery Plugins Authoring Guide 내부 { }에 선언 된 모든 변수 는 비공개이며 더 나은 캡슐화를 허용하는 외부에 보이지 않습니다.
{}자체적으로 JavaScript에서 새 범위를 만들지 마십시오. 범위는 함수 선언에 의해 생성됩니다.
다른 사람들이 말했듯이 둘 다 즉시 호출되는 익명 함수를 정의합니다. 일반적으로 클래스에 대한 정적 전용 범위를 만들기 위해이 구조에서 JavaScript 클래스 선언을 래핑합니다. 그런 다음 상수 데이터, 정적 메서드, 이벤트 처리기 또는 해당 범위에있는 다른 모든 항목을 배치 할 수 있으며 클래스의 인스턴스에만 표시됩니다.
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
이 예에서 MyObject클래스는 MyLibrary네임 스페이스에 할당 되므로 액세스 할 수 있습니다. incrementingID그리고 somePrivateStaticMethod()직접 익명 함수의 범위를 외부에서 액세스 할 수 없습니다.
그것은 기본적으로 네임 스페이스입니다. JavaScript 코드의 것입니다.
예를 들어, 변수 또는 함수를 거기에 배치 할 수 있으며 외부에서는 해당 범위에 존재하지 않습니다. 따라서 거기에 모든 것을 캡슐화하면 충돌에 대해 걱정할 필요가 없습니다.
()자기 호출에 마지막 수단에서. 익명 함수의 인수가 될 인수를 추가 할 수도 있습니다. 나는 자주 jQuery로 이것을하고, 왜 그런지 알 수있다.
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
Evan Trimboli 는 그의 대답 에서 나머지를 다룹니다 .
위의 코드가하는 일은 1 번 줄에 익명 함수를 만든 다음 0 개의 인수를 사용하여 3 번 줄에서 호출하는 것입니다. 모든 함수는 해당 익명 함수 내에서만 액세스 할 수 있기 때문에 이는 해당 라이브러리 내에 정의 된 모든 함수와 변수를 효과적으로 캡슐화합니다.
이것은 좋은 방법이며, 그 이유는 변수와 함수로 전역 네임 스페이스를 오염시키지 않기위한 것입니다. 이는 사이트 전체의 다른 Javascript에 의해 방해받을 수 있습니다.
함수가 호출되는 방식을 명확히하기 위해 간단한 예를 고려하십시오.
이 한 줄의 자바 스크립트가 포함 된 경우 명시 적으로 호출하지 않고 자동으로 호출됩니다.
alert('hello');
따라서 그 아이디어를이 예제에 적용하십시오.
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
익명 함수가 이전 예제와 같이 호출되기 때문에 최종 결과는 비슷합니다.
//here, the anonymous function is invoked간단한,하지만 나는 :) 전에 그것을 보지 못했다