답변:
가변 범위 지정에 관한 것입니다. 자체 실행 기능에 선언 된 변수는 기본적으로 자체 실행 기능 내에서 코드를 작성할 때만 사용할 수 있습니다. 이를 통해 다른 JavaScript 코드 블록에서 변수의 이름을 지정하는 방법에 관계없이 코드를 작성할 수 있습니다.
예를 들어 Alexander 의 의견에서 언급했듯이 :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
정의되지 않았 으므로 먼저 로그 3
에 기록한 후 다음에 오류를 발생시킵니다 .console.log
foo
var
이 같은 : ...function(){ foo=3;}
? 전역 변수를 설정했을까요?
function(){ var foo = 3; alert(foo); }; alert(foo);
그래서 난 아직도 이해가 안가
단순합니다. 매우 평범한 모습, 거의 위안 :
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
그러나 고급 문자를 기본 레벨 표현으로 변환하는 정말 편리한 자바 스크립트 라이브러리를 페이지에 포함 시키면 어떻게됩니까?
무엇을 기다립니다?
누군가가 어떤 종류의 악센트가있는 문자를 입력하면 내 프로그램에서 '영어'문자 AZ 만 원합니까? 음 ... 스페인어 'ñ'과 프랑스어 'é'문자는 'n'과 'e'의 기본 문자로 변환 될 수 있습니다.
그래서 좋은 사람이 내 사이트에 포함시킬 수있는 포괄적 인 문자 변환기를 작성했습니다 ... 포함합니다.
한 가지 문제 : 내 함수와 같은 '이름'이라는 함수가 있습니다.
이것이 충돌이라고합니다. 같은 범위 에서 선언 된 두 함수가 있습니다 에서 같은 이름으로 있습니다. 우리는 이것을 피하고 싶습니다.
그래서 우리는 어떻게 든 코드의 범위를 정해야합니다.
자바 스크립트에서 코드를 범위를 지정하는 유일한 방법은 함수로 코드를 래핑하는 것입니다.
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
문제가 해결 될 수도 있습니다. 이제 모든 것이 동봉되었으며 개폐 중괄호 내에서만 접근 할 수 있습니다.
우리는 함수에 함수가 있습니다 ...보기에는 이상하지만 완전히 합법적입니다.
단 하나의 문제. 코드가 작동하지 않습니다. userName 변수는 콘솔에 에코되지 않습니다!
기존 코드 블록 뒤에 함수에 대한 호출을 추가하여이 문제를 해결할 수 있습니다.
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
또는 전에!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
부차적 인 우려 : 'main'이라는 이름이 아직 사용되지 않았을 가능성은 무엇입니까? ... 매우 슬림합니다.
더 많은 범위가 필요합니다. 그리고 main () 함수를 자동으로 실행하는 방법.
이제 자동 실행 기능 (또는 자체 실행, 자체 실행 등)에 대해 살펴 보겠습니다.
((){})();
구문은 죄로 어색합니다. 그러나 작동합니다.
함수 정의를 괄호로 묶고 매개 변수 목록 (다른 세트 또는 괄호!)을 포함하면 함수 호출 역할을합니다 .
자체 실행 구문을 사용하여 코드를 다시 살펴 보겠습니다.
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
따라서 여러분이 읽은 대부분의 자습서에서 이제 '익명 자체 실행'이라는 용어 또는 이와 유사한 용어가 적용됩니다.
수년간의 전문적인 개발 끝에, 디버깅 목적으로 작성한 모든 함수의 이름을 지정할 것을 강력히 권합니다 .
문제가 발생하면 브라우저에서 역 추적을 확인하게됩니다. 스택 추적의 항목 이름이 있으면 코드 문제를 좁히는 것이 항상 더 쉽습니다!
엄청나게 긴 바람과 나는 그것이 도움이되기를 바랍니다!
:)
자체 호출 (자동 호출이라고도 함)은 함수가 정의에 따라 즉시 실행될 때입니다. 이것은 핵심 패턴이며 JavaScript 개발의 다른 많은 패턴의 기초가됩니다.
나는 큰 팬입니다 :)
엄청나게 – (왜 좋은 말을해야합니까?)
여기 더 .
네임 스페이스. JavaScript의 범위는 기능 수준입니다.
나는 암시 적 세계를 언급 한 답을 전혀 믿을 수 없다.
(function(){})()
구조는, 나에게 어느 것이 더 큰 문제입니다, 묵시적 전역에 대해 보호하지 않습니다 참조 http://yuiblog.com/blog/2006/06/01/global-domination/
기본적으로 함수 블록은 정의한 모든 종속 "전역 변수"가 프로그램에 국한되어 있는지 확인하지만 암시 적 전역을 정의하는 것을 방지하지는 않습니다. JSHint 은이 동작을 방지하는 방법에 대한 권장 사항을 제공 할 수 있습니다.
간결한 var App = {}
구문은 비슷한 수준의 보호를 제공하며 '공개'페이지에있을 때 기능 블록에 래핑 될 수 있습니다. ( 이 구문을 사용하는 라이브러리의 실제 예는 Ember.js 또는 SproutCore 를 참조하십시오 )
지금까지로 private
특성 가고, 그들은 종류의 공용 프레임 워크 또는 라이브러리를 생성하지 않는 과대 평가의, 그러나 당신이 그들을 구현해야하는 경우, 더글러스 크록 포드는 좋은 아이디어를 가지고있다.
나는 모든 답변을 읽었으며 여기에 매우 중요한 것이 빠져 있습니다 . 자체 실행 익명 함수가 필요한 이유 또는 " IIFE (Inmediately Invoked Function Expression) "가 더 나은 이유는 다음 두 가지가 있습니다 .
첫 번째는 매우 잘 설명되었습니다. 두 번째 예는 다음 예제를 연구하십시오.
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
주의 1 : 우리는 함수를 할당하지 않고 MyClosureObject
, 그 함수를 호출 한 결과를 더 많이 제공 합니다 . ()
마지막 줄에 유의하십시오 .
주의 2 : Javascript의 함수에 대해 추가로 알아야 할 것은 내부 함수가 함수 의 매개 변수 및 변수 에 액세스 할 수 있다는 것 입니다.
몇 가지 실험을 해보자.
내가 얻을 수있는 MyName
사용 getMyName
하고 그것을 작동합니다 :
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
다음과 같은 독창적 인 접근 방식이 작동하지 않습니다.
console.log(MyClosureObject.MyName);
// undefined
그러나 다른 이름을 설정하고 예상 결과를 얻을 수 있습니다.
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
편집 : 위의 예 MyClosureObject
에서 new
접두사 없이 사용되도록 설계되었으므로 일반적으로 대문자로 사용해서는 안됩니다.
매개 변수가 있고 "Bunch of code"가 함수를 반환합니까?
var a = function(x) { return function() { document.write(x); } }(something);
폐쇄. 에 something
지정된 함수가 사용하는 값입니다 a
. something
다양한 값 (for loop)을 가질 수 있으며 새로운 기능을 가질 때마다.
var x = something;
를 통해 외부 함수를 x
하지만 매개 변수로 : IMO는이 방법은 ... 더 읽기입니다
x
하고 어휘 범위에 직접 의존 하는 경우 새 값이 사용됩니다 document.write(something)
.
스코프 격리. 따라서 함수 선언 내부의 변수는 외부 네임 스페이스를 오염시키지 않습니다.
물론 JS 구현의 절반에서 어쨌든 그들은 구현할 것입니다.
다음은 자체 호출 익명 함수가 유용한 방법에 대한 확실한 예입니다.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
산출: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
산출: 0, 1, 2, 3, 4...
let
대신 var
첫 번째 경우하는 것은 괜찮을 것입니다.
자체 실행 기능은 변수의 범위를 관리하는 데 사용됩니다.
변수의 범위는 변수가 정의 된 프로그램의 영역입니다.
전역 변수에는 전역 범위가 있습니다. JavaScript 코드의 어느 곳에서나 정의되며 함수 내에서도 스크립트 내 어디에서나 액세스 할 수 있습니다. 반면, 함수 내에서 선언 된 변수는 함수 본문 내에서만 정의됩니다. 그것들은 지역 변수이며 지역 범위가 있으며 그 기능 내에서만 액세스 할 수 있습니다. 함수 매개 변수는 로컬 변수로 계산되며 함수 본문 내에서만 정의됩니다.
아래에 표시된 것처럼 함수 내에서 전역 변수에 액세스 할 수 있으며 함수 본문 내에서 로컬 변수가 이름이 같은 전역 변수보다 우선합니다.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
따라서 기본적으로 자체 실행 기능을 사용하면 변수가 다른 JavaScript 코드 블록에서 명명되는 방식에 관계없이 코드를 작성할 수 있습니다.
짧은 대답은 글로벌 (또는 그 이상) 범위의 오염을 방지하는 것입니다.
IIFE (즉시 호출 함수 표현식)는 스크립트를 플러그인, 애드온, 사용자 스크립트 또는 다른 사람의 스크립트와 함께 작동 할 것으로 예상되는 스크립트로 작성 하는 가장 좋은 방법 입니다 . 이렇게하면 정의한 변수가 다른 스크립트에 바람직하지 않은 영향을주지 않습니다.
이것은 IIFE 표현을 작성하는 다른 방법입니다. 개인적으로 다음 방법을 선호합니다.
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
위의 예에서 IIFE가 효율성과 성능에 영향을 줄 수 있다는 것은 매우 분명합니다. 한 번만 실행될 것으로 예상되는 기능이 한 번만 실행 된 다음 void로 덤프되기 때문 입니다. 이는 함수 또는 메소드 선언이 메모리에 남아 있지 않음을 의미합니다.
void
전에 그 사용법을 보지 못했습니다 . 나는 그것을 좋아한다.
이 질문에 대한 답변이 모두 준비된 것처럼 보이지만 어쨌든 입력 내용을 게시하겠습니다.
자체 실행 기능을 언제 좋아하는지 알고 있습니다.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
이 함수를 사용하면 추가 코드를 사용하여 일반적으로 사용되는 변수 설정 또는 수학 방정식 실행과 같은 더 깨끗한 코드의 childObjects 속성 및 속성을 정의 할 수 있습니다. 오! 또는 오류 점검. 중첩 된 객체 인스턴스화 구문으로 제한되는 것과는 대조적으로 ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
일반적으로 코딩은 똑같은 일을 많이하는 모호한 방법이 많으므로 "왜 귀찮게합니까?" 그러나 더 이상 기본 / 핵심 교장에만 의존 할 수없는 새로운 상황이 계속 나타납니다.
간단한 질문이 있습니다 : "자바 스크립트에서 언제 이것을 사용하겠습니까 : ..."
@ken_browning 및 @sean_holding의 답변이 마음에 들지만 여기에 언급되지 않은 다른 유스 케이스가 있습니다.
let red_tree = new Node(10);
(async function () {
for (let i = 0; i < 1000; i++) {
await red_tree.insert(i);
}
})();
console.log('----->red_tree.printInOrder():', red_tree.printInOrder());
여기서 Node.insert는 일부 비동기 조치입니다.
내 함수 선언에서 async 키워드없이 await를 호출 할 수 없으며 나중에 사용하기 위해 명명 된 함수가 필요하지 않지만 삽입 호출을 기다려야하거나 다른 풍부한 기능이 필요합니다 (누군가 아는가?) .