자바 스크립트 함수 범위 지정 및 호이 스팅


90

방금 Ben Cherry의 JavaScript Scoping and Hoisting에 대한 훌륭한 기사를 읽었습니다 .

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);

위의 코드를 사용하면 브라우저는 "1"을 경고합니다.

왜 "1"을 반환하는지 잘 모르겠습니다. 그가 말한 것 중 일부는 다음과 같이 떠 오릅니다. 모든 함수 선언이 맨 위로 올라갑니다. 함수를 사용하여 변수의 범위를 지정할 수 있습니다. 여전히 나를 위해 클릭하지 않습니다.

답변:


120

기능 호이 스팅은 기능이 범위의 맨 위로 이동하는 것을 의미합니다. 그건,

function b() {  
   a = 10;  
   return;  
   function a() {} 
} 

interpeter에 의해 이것으로 다시 쓰여질 것입니다

function b() {
  function a() {}
  a = 10;
  return;
}

이상 해요?

또한이 경우

function a() {}

똑같이 행동했다

var a = function () {};

따라서 본질적으로 코드가 수행하는 작업은 다음과 같습니다.

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"

2
그래서 모든 함수 선언은 결국 변수에 할당됩니까?
dev.e.loper 2011 년

15
@ dev.e.loper 예, 자바 스크립트에서 함수는 문자열과 숫자처럼 일급 객체입니다. 즉, 변수로 정의되고 다른 함수로 전달되고 배열에 저장되는 등의 작업이 가능합니다.
Peter Olson

4
함수 본문은 "재 작성"되지 않습니다. 다양한 ECMAScript 표준은 코드 실행이 시작되기 전에 변수 및 함수 선언이 처리됨을 명확하게 명시합니다. 즉, 아무것도 움직이지 않고 실행 순서에 관한 것입니다 (따라서 이동 또는 재 배열을 유추하는 "게양"이라는 용어를 싫어함). 다시 작성된 코드에서 선언 var a은 함수 선언 앞에 a = 1있어야 하고 할당 은 뒤에 있어야합니다. 그러나 이것은 파서, 토크 나이저, 인터프리터, 컴파일러 등에 의해 실제로 발생하도록 지정되어 있지 않습니다 .
RobG 2015

3
@RobG 물론, 설명을 작은 "아이들에게 거짓말" 이라고 부를 수 있겠지만 결국 코드가 문자 그대로 재 배열 되든 실행 순서가 재 배열 되든 결국 동작은 동일합니다. 실제로 뒤에서 일어나는 일은 학문적 관심사이며 구현에 따라 달라질 수도 있습니다.
Peter Olson 2015

7
"또한이 경우에는 " function a() {}와 동일하게 작동했습니다. var a = function () {};"  -이것은 두 가지 측면에서 잘못된 것입니다. 첫째, 어떤 것이 있다면 var a = function a() {};(함수가 실제로 익명이 아님), 둘째,이 두 형식은 서로 바꿔서 사용할 수 없습니다. 부분 var a = function a() {};var a;들어 올려 졌을 것입니다. 그 a = function a() {};부분은 여전히 ​​return 문 뒤에있을 것입니다. 원래 형식은 함수 표현식이 아니라 함수 선언이기 때문에 실제로 전체적으로 호이스트됩니다.
user4642212

6

기억해야 할 것은 전체 함수를 구문 분석하고 실행하기 전에 모든 변수 선언을 해결한다는 것입니다. 그래서....

function a() {} 

정말된다

var a = function () {}

var a 로컬 범위로 강제하고 변수 범위는 전체 함수를 통하므로 전역 변수는 여전히 1입니다.을 함수로 만들어서 로컬 범위로 선언했기 때문입니다.


5

기능 a은 기능 내부에 게양됩니다 b.

var a = 1; 
function b() { 
   function a() {} 
   a = 10; 
   return;
} 
b(); 
alert(a);

거의 다음을 사용하는 것과 같습니다 var.

var a = 1; 
function b() { 
   var a = function () {};
   a = 10; 
   return;
} 
b(); 
alert(a);

함수는 로컬로 선언되며 설정 a은 전역 변수가 아닌 로컬 범위에서만 발생합니다.


1
이 줄 "var a = function () {};"은 모든 것을 명확하게합니다. 기본적으로 JavaScript는 동적 언어이며 "function"은 JavaScript의 객체이기도합니다.
리팩터링

3
  1. 함수 선언 function a(){}이 먼저 호이스트되고처럼 동작 var a = function () {};하므로 로컬 범위 a에서 생성됩니다.
  2. 같은 이름의 변수가 두 개있는 경우 (하나는 전역에서 다른 하나는 로컬에서) 지역 변수는 항상 전역 변수보다 우선합니다.
  3. 을 설정 하면 전역 a=10변수 a가 아닌 로컬 변수가 설정 됩니다.

따라서 전역 변수의 값은 동일하게 유지되고 경고 1이 표시됩니다.


1

function a() { }함수에 a로컬 변수 를 생성하는 함수 문 b입니다. 또는 function 문이 실행
되는지 여부에 관계없이 함수가 구문 분석 될 때 변수가 생성됩니다 var.

a = 10 이 지역 변수를 설정합니다.


실제로 추가하지 않는 한 함수 가 실행될 때 전역 범위 a = 10에서 변수를 설정합니다 (해당 지시문을 지원하는 환경에서). b"use strict"
Sean Vieira

@Sean : 아니요, 함수 문이 로컬 식별자를 생성하기 때문입니다.
SLaks

... 그리고 .... 당신 말이 맞아요. 기능 호이 스팅의 특정 결과를 깨닫지 못했습니다. 감사!
Sean Vieira

1

이 작은 코드 조각에서 경합의 뼈대는 무엇입니까?

사례 1 :

다음과 같이 function a(){}본문에 정의를 포함 function b합니다.logs value of a = 1

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

사례 2

다음과 같이 function a(){}본문 내부의 정의를 제외 function b합니다.logs value of a = 10

var a = 1;
function b() {
  a = 10;  // overwrites the value of global 'var a'
  return;
}
b();
console.log(a); // logs a = 10

관찰은 명령문 console.log(a)이 다음 값을 기록 한다는 사실을 깨닫는 데 도움이 됩니다.

사례 1 : a = 1

사례 2 : a = 10

Posits

  1. var a 전역 범위에서 어휘 적으로 정의되고 선언되었습니다.
  2. a=10 이 문은 값을 10으로 재 할당하고 있으며 어휘 적으로 함수 b 내에 있습니다.

두 경우에 대한 설명

로 인해 function definition with name property(A)가 동일하다 variable a. variable a내부는 function body b로컬 변수가된다. 이전 행은 a의 전역 값이 그대로 유지되고 a의 로컬 값이 10으로 업데이트됨을 의미합니다.

그래서 우리가 말하고자하는 것은 아래 코드가

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

JS 인터프리터는 다음과 같이 해석합니다.

var a = 1;
function b() {
  function a() {}
  a = 10;
  return;


}
b();
console.log(a); // logs a = 1

그러나 함수 b 외부 function a(){} definition에서 value of 'a'선언되고 정의 된 ,를 제거하면 해당 값을 덮어 쓰고 경우 2에서 10으로 변경합니다. 값은 a=10전역 선언을 참조하기 때문에 덮어 쓰여지고 로컬로 선언 될 경우 서면 var a = 10;.

var a = 1;
function b() {
  var a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;
}
b();
console.log(a); // logs a = 1

우리는 변화에 의해 우리의 의심을 더욱 명확히 할 수 name property있는을 function a(){} definition다른 이름보다'a'

var a = 1;
function b() {
  a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;

  function foo() {}
}
b();
console.log(a); // logs a = 1

1

호이 스팅은 이해하기 쉽도록 만든 개념입니다. 실제로 발생하는 것은 범위와 관련하여 선언이 먼저 수행되고 그 이후에 할당이 발생합니다 (동시에 아님).

선언이 발생하는 경우 var a, 다음 function b그 안에 b범위 function a선언된다.

이 함수 a는 전역 범위에서 오는 변수 a를 숨 깁니다.

선언이 완료되면 값 할당이 시작되고 전역 a이 값 을 얻고 1a 내부 function b10. 할 때 alert(a)실제 전역 범위 변수를 호출합니다. 코드를 조금만 변경하면 더 명확 해집니다.

        var a = 1;

    function b() {
        a = 10;
        return a;

        function a() { }
    }

    alert(b());
    alert(a);

1
codeschool.com의 과정 에서조차도 많은 전문가들이 발생하는 일에 대한 단순한 견해에 지나지 않는 호이 스팅을 언급하고 실제로 호이 스팅은 전혀 발생하지 않는 것이 궁금합니다. 참고 : 1) developer.mozilla.org/en-US/docs/Glossary/Hoisting 2) 존 Resig 씨, 곰 bebeault, 요시프 마라으로 자바 스크립트 닌자 2 / E의 비밀 제 5 장
adnan2nd

1

놀랍게도 여기에 언급 된 답변은 범위 체인에서 실행 컨텍스트의 관련성을 언급하지 않습니다.

JavaScript 엔진은 현재 실행중인 코드를 실행 컨텍스트에 래핑합니다. 기본 실행 컨텍스트는 전역 실행 컨텍스트입니다. 새 함수가 호출 될 때마다 새 실행 컨텍스트가 생성되어 실행 스택에 배치됩니다. 다른 프로그래밍 언어에서 호출 스택에있는 스택 프레임을 생각해보십시오. 후입 선출법. 이제 각 실행 컨텍스트에는 JavaScript의 자체 변수 환경과 외부 환경이 있습니다.

아래 예제를 데모로 사용하겠습니다.

1) 먼저 글로벌 실행 컨텍스트의 생성 단계에 들어갑니다. Lexical Environment의 외부 환경과 가변 환경이 모두 생성됩니다. 전역 개체가 설정되고이를 가리키는 특수 변수 'this'와 함께 메모리에 배치됩니다. 함수 a와 해당 코드 및 정의되지 않은 값을 가진 myVar 변수는 전역 변수 환경의 메모리에 배치됩니다. 함수 a의 코드가 실행되지 않는다는 점에 유의하는 것이 중요합니다. 기능 a와 함께 메모리에 저장됩니다.

2) 둘째, 실행 컨텍스트의 실행 단계입니다. myVar는 더 이상 정의되지 않은 값이 아닙니다. 값 1로 초기화되며 전역 변수 환경에 저장됩니다. 함수 a가 호출되고 새 실행 컨텍스트가 생성됩니다.

3) 함수 a의 실행 컨텍스트에서 자체 실행 컨텍스트의 생성 및 실행 단계를 거칩니다. 자체 외부 환경과 가변 환경이 있으므로 자체 어휘 환경이 있습니다. 함수 b와 변수 myVar는 변수 환경에 저장됩니다. 이 변수 환경은 전역 변수 환경과 다릅니다. 함수 a는 전역 실행 컨텍스트와 동일한 수준에서 어휘 적으로 (물리적으로 코드에서) 위치하므로 외부 환경은 전역 실행 컨텍스트입니다. 따라서 함수 a가 변수 환경에없는 변수를 참조하는 경우 스코프 체인을 검색하고 글로벌 실행 컨텍스트의 변수 환경에서 변수를 찾으려고합니다.

4) 함수 b는 함수 a에서 호출됩니다. 새 실행 컨텍스트가 생성됩니다. 함수 a에 어휘 적으로 있기 때문에 외부 환경은 a입니다. 따라서 myVar를 참조 할 때 myVar는 함수 b의 변수 환경에 없기 때문에 함수 a의 변수 환경을 찾습니다. 거기에서 그것을 찾고 console.log는 2를 인쇄합니다. 그러나 변수가 함수 a의 변수 환경에 없다면, 함수 a의 외부 환경이 전역 실행 컨텍스트이기 때문에 스코프 체인은 그곳에서 계속 검색 할 것입니다.

5) 함수 b와 a가 실행을 마치면 Execution Stack에서 팝됩니다. 단일 스레드 JavaScript 엔진은 전역 실행 컨텍스트에서 계속 실행됩니다. b 함수를 호출합니다. 그러나 전역 변수 환경에는 b 함수가 없으며 전역 실행 컨텍스트에서 검색 할 다른 외부 환경이 없습니다. 따라서 JavaScript 엔진에서 예외가 발생합니다.

function a(){
  function b(){
    console.log(myVar);
  }

  var myVar = 2;
  b();
}

var myVar = 1;
a();
b();
> 2
> Uncaught ReferenceError: b is not defined

아래 예는 작동중인 스코프 체인을 보여줍니다. 함수 b의 실행 컨텍스트의 변수 환경에는 myVar가 없습니다. 그래서 그것은 기능인 외부 환경을 검색합니다. 함수 a에는 변수 환경에도 myVar가 없습니다. 따라서 엔진 검색 기능 a의 외부 환경은 전역 실행 컨텍스트의 외부 환경이고 myVar가 여기에 정의되어 있습니다. 따라서 console.log는 1을 인쇄합니다.

function a(){
  function b(){
    console.log(myVar);
  }

  b();
}

var myVar = 1;
a();
> 1

실행 컨텍스트 및 외부 환경 및 변수 환경을 포함하여 연관된 어휘 환경과 관련하여 JavaScript에서 변수 범위 지정을 활성화합니다. 동일한 함수를 여러 번 호출하더라도 각 호출에 대해 고유 한 실행 컨텍스트를 생성합니다. 따라서 각 실행 컨텍스트는 변수 환경에서 자체 변수 사본을 갖게됩니다. 변수 공유가 없습니다.


0

변수 이름이 함수 이름이 "a"를 의미하는 것과 동일하기 때문에 발생합니다. 따라서 Javascript hoisting으로 인해 이름 충돌을 해결하려고 시도하고 a = 1을 반환합니다.

또한 "JavaScript Hoisting" http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html 에 대한이 게시물을 읽을 때까지 이것에 대해 혼란 스러웠습니다 .

도움이 되었기를 바랍니다.


0

여기에 더 많은 주석과 함께 연주 할 수있는 바이올린이있는 대답에 대한 요약이 있습니다.

// hoisting_example.js

// top of scope ie. global var a = 1
var a = 1;

// new scope due to js' functional (not block) level scope
function b() {
    a = 10; // if the function 'a' didn't exist in this scope, global a = 10
  return; // the return illustrates that function 'a' is hoisted to top
  function a(){}; // 'a' will be hoisted to top as var a = function(){};
}

// exec 'b' and you would expect to see a = 10 in subsequent alert
// but the interpreter acutally 'hoisted' the function 'a' within 'b' 
// and in doing so, created a new named variable 'a' 
// which is a function within b's scope
b();

// a will alert 1, see comment above
alert(a);

https://jsfiddle.net/adjavaherian/fffpxjx7/


0

scpope 및 폐쇄 및 호이 스팅 (var / function)

  1. scpope : 전역 변수는 모든 위치 (전체 파일 범위)에서 액세스 할 수 있으며, 로컬 변수는 로컬 범위 (함수 / 블록 범위)에서만 액세스 할 수 있습니다!
    참고 : 함수에서 var 키워드를 사용하지 않는 지역 변수는 전역 변수가됩니다!
  2. 클로저 : 로컬 스코프 (부모 함수)와 글로벌 스코프에 접근 할 수있는 다른 함수 내부의 함수, 그러나 그것이 변수라면 다른 사람이 접근 할 수 없습니다! 그렇지 않으면 반환 값으로 반환하십시오!
  3. hoisting : 값 또는 null을 할당하는 것보다 vars / function 선언 / 선언을 모두 스코프 맨 위로 이동합니다!
    참고 : 값을 이동하지 않고 선언 만 이동합니다!

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined



0

Hoisting JavaScript에서 변수 선언은 코드가 실행되기 전에 프로그램을 통해 실행됩니다. 따라서 코드에서 변수를 선언하는 것은 처음에 선언하는 것과 같습니다.


0

모두 변수 'a'의 범위에 따라 다릅니다. 스코프를 이미지로 만들어 설명하겠습니다.

여기서 JavaScript는 3 개의 범위를 생성합니다.

i) 글로벌 범위. ii) 함수 b () 범위. iii) 함수 a () 범위.

여기에 이미지 설명 입력

'alert'메소드 범위를 호출하면 해당 시간이 Global에 속하므로 Global 범위에서 변수 'a'의 값이 1 인 값만 선택합니다.


0

긴 포스트!

그러나 그것은 공기를 맑게 할 것입니다!

Java Script가 작동하는 방식은 두 단계 프로세스를 포함한다는 것입니다.

  1. 컴파일 (말하자면)-이 단계는 변수 및 함수 선언과 해당 범위를 등록합니다. 이 평가 함수식 포함하지 않는다 : var a = function(){}(할당 등 또는 가변 식 3으로 x경우의 var x =3;. 이는 아무것도하지만 RHS 부의 평가 없음)

  2. 통역사 : 실행 / 평가 부분입니다.

이해하려면 아래 코드의 출력을 확인하십시오.

//b() can be called here!
//c() cannot be called.
console.log("a is " + a);
console.log("b is " + b);
console.log("c is " + c);
var a = 1;
console.log("Now, a is " + a);
var c = function() {};
console.log("Now c is " + c);

function b() {
  //cannot write the below line:
  //console.log(e); 
  //since e is not declared.
  e = 10; //Java script interpreter after traversing from this function scope chain to global scope, is unable to find this variable and eventually initialises it with value 10 in global scope.
  console.log("e is " + e) //  works!
  console.log("f is " + f);
  var f = 7;
  console.log("Now f is " + f);
  console.log("d is " + d);
  return;

  function d() {}
}
b();
console.log(a);

그것을 깨자 :

  1. 컴파일 단계에서 'a'는 값이 ' undefined'인 전역 범위에 등록됩니다 . ' c'도 마찬가지입니다 .이 순간의 값은 ' undefined'가 아니라 ' function()'입니다. ' b'은 전역 범위의 함수로 등록됩니다. 내부 b의 범위는 ' f'이 순간과 기능 "으로 정의되지 유용한 변수로 등록 될 d등록된다 '.

  2. 인터프리터가 실행되면 인터프리터가 function()실제 표현식 라인에 도달하기 전에 선언 된 변수 (식이 아닌)에 액세스 할 수 있습니다. 따라서 변수는 ' undefined' 로 인쇄 되고 선언 된 익명 함수를 더 일찍 호출 할 수 있습니다. 그러나 표현식 초기화 전에 선언되지 않은 변수에 액세스하려고하면 다음과 같은 오류가 발생합니다.

console.log(e)
e = 3;

이제 같은 이름의 변수와 함수 선언이 있으면 어떻게됩니까?

대답은 -함수는 항상 이전에 호이스트되며 동일한 이름 변수가 선언되면 중복으로 처리되고 무시됩니다. 순서는 중요하지 않습니다. 함수에는 항상 우선 순위가 부여됩니다. 그러나 평가 단계에서 변수 참조를 무엇이든 변경할 수 있습니다 (마지막 할당을 저장합니다). 아래 코드를 살펴보십시오.

var a = 1;
console.log("a is " + a);

function b() {
  console.log("a inside the function b is " + a); //interpreter finds                                'a' as function() in current scope. No need to go outside the scope to find 'a'.
  a = 3; //a changed
  console.log("Now a is " + a);
  return;

  function a() {}
}
var a; //treated as duplicate and ignored.
b();
console.log("a is still " + a + " in global scope"); //This is global scope a.


0

Hoisting은 JavaScript의 행동 개념입니다. 호이 스팅 (이동)은 변수를 선언하는 방법과 위치를 설명하는 개념입니다.

JavaScript에서는 함수 선언과 변수 선언이 JavaScript 인터프리터에 의해 포함 된 범위의 맨 위로 항상 보이지 않게 이동 ( "게재")되기 때문에 JavaScript에서 변수를 사용한 후에 선언 할 수 있습니다.

대부분의 경우 두 가지 유형의 호이 스팅이 발생합니다.

1. 가변 선언 게양

이 코드 조각으로 이것을 이해할 수 있습니다.

 a = 5; // Assign 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
 var a; // Declare a
  //output-> 5

여기서 변수 a의 선언은 컴파일 할 때 자바 스크립트 인터프리터에 의해 보이지 않게 맨 위에 호스팅됩니다. 그래서 우리는 a의 가치를 얻을 수있었습니다. 그러나 이러한 변수 선언 접근 방식은 이미 이와 같이 변수를 맨 위에 선언해야하므로 권장되지 않습니다.

 var a = 5; // Assign and declare 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
  // output -> 5

다른 예를 고려하십시오.

  function foo() {
     console.log(x)
     var x = 1;
 }

실제로 다음과 같이 해석됩니다.

  function foo() {
     var x;
     console.log(x)
     x = 1;
  }

이 경우 x는 정의되지 않습니다.

변수 선언을 포함하는 코드가 실행되었는지 여부는 중요하지 않습니다. 이 예를 고려하십시오.

  function foo() {
     if (false) {
         var a = 1;
     }
     return;
     var b = 1;
  }

이 기능은 다음과 같습니다.

  function foo() {
      var a, b;
      if (false) {
        a = 1;
     }
     return;
     b = 1;
  }

변수 선언에서는 할당이 아닌 변수 정의 만 호이스트합니다.

  1. 기능 선언 게양

가변 권상과 달리 기능 본체 또는 할당 된 값도 권상됩니다. 이 코드를 고려하십시오

 function demo() {
     foo(); // this will give error because it is variable hoisting
     bar(); // "this will run!" as it is function hoisting
     var foo = function () {
         alert("this would not run!!");
     }
     function bar() { 
         alert("this will run!!");
     }
 }
 demo();

이제 변수 및 함수 호이 스팅을 모두 이해 했으므로 이제이 코드를 이해하겠습니다.

var a = 1;
function b() {
  a = 10;
  return;
   function a() {}
}
b();
alert(a);

이 코드는 다음과 같습니다.

var a = 1;                 //defines "a" in global scope
 function b() {  
   var a = function () {}; //defines "a" in local scope 
    a = 10;                 //overwrites local variable "a"
    return;      
 }       
 b();       
 alert(a); 

함수 a ()는 b () 내부에 지역 범위를 갖습니다. (함수 호이 스팅의 경우에만) 정의로 코드를 해석하는 동안 a ()가 맨 위로 이동하므로 a는 이제 로컬 범위를 가지므로 a의 전역 범위에 영향을주지 않고 함수 b () 내에 자체 범위를가집니다. .


0

내 지식으로 볼 때 변수 선언 및 함수 선언과 함께 호이 스팅이 발생합니다.

a = 7;
var a;
console.log(a) 

자바 스크립트 엔진 내부에서 일어나는 일 :

var a;
a = 7;
console.log(a);
// 7

또는:

console.log(square(7)); // Output: 49
function square(n) { return n * n; }

다음과 같이됩니다.

function square(n) { return n * n; }
console.log(square(7)); // 49

그러나 변수 할당, 함수 표현식 할당과 같은 할당은 호이스트되지 않습니다. 예 :

console.log(x);
var x = 7; // undefined

다음과 같이 될 수 있습니다.

var x;
console.log(x); // undefined
x = 7;

0

자바 스크립트 호스팅을 한 문장으로 설명하는 것은 변수이며 함수는 선언 된 범위의 맨 위로 올라갑니다.

여기에 이미지 설명 입력

나는 당신이 초보자라고 가정하고, 처음에 올바르게 호이 스팅을 이해하기 위해 정의되지 않은 것과 ReferenceError 의 차이점을 이해했습니다.

 var v;
 console.log(v);
 console.log(abc);
/*
The output of the above codes are:
undefined
ReferenceError: abc is not defined*/

이제 벨로우즈 코드에서 무엇을 볼 수 있습니까? 변수 및 함수 표현식이 해제됩니다.

<script>
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
</script>

그러나 변수와 기능이 모두 범위의 맨 위에 올랐다는 증거가있는 실제 그림 :

console.log(totalAmo);
console.log(getSum(8,9));
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
console.log(totalAmo);
console.log(getSum(9,7));

처음 두 로그의 출력되어 정의되지 않은형식 오류 : getSum는 함수가 아닙니다 var에 모두 있기 때문에 totalAmogetSum가 울부 짖는 소리와 같은 그들의 범위의 상단에 게양된다

 <script>
        var totalAmo;
        var getSum;

        console.log(totalAmo);
        console.log(getSum(8,9));
        var totalAmo = 8;
        var getSum = function(a, b){
            return a+b;
        }
        console.log(totalAmo);
        console.log(getSum(9,7));
    </script>

그러나 함수 선언의 경우 전체 함수가 범위 상단에 올랐습니다.

console.log(getId());
function getId(){
   return 739373;
}
/* output: 739373, because the whole function hoisted on the top of the scope.*/

이제 동일한 논리가 기능 범위 내에서 선언 된 변수, 함수 경험 및 함수 선언에 대해서도 적용됩니다. 요점 : 파일 상단에 올리지 않습니다 .

function functionScope(){
            var totalAmo;
            var getSum;

            console.log(totalAmo);
            console.log(getSum(8,9));
            var totalAmo = 8;
            var getSum = function(a, b){
                return a+b;
            }
        }

따라서 var 키워드 를 사용하면 해당 범위 (전역 범위 및 함수 범위)의 맨 위에 올려 진 변수 및 함수가 있습니다. letconst 어떻습니까? , CONST 및하자 여전히 글로벌 범위와 VAR이처럼 기능 범위,하지만 const를 모두 인식하고 변수도 범위를 차단라는 또 다른 범위를 인식 할 수 있습니다. for 루프, if else 문, while 루프 등과 같은 코드 블록이있을 때마다 블록 범위가 존재합니다.

const를 사용하고이 블록 범위에서 변수를 선언하기 위해 let을 사용하면 변수 선언은 해당 블록의 맨 위에 만 올릴 것이며 부모 함수 또는 맨 위에 올리지 않을 것입니다. 게양되는 글로벌 범위.

 function getTotal(){
            let total=0;
            for(var i = 0; i<10; i++){
                let valueToAdd = i;
                var multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

abobe 예제의 변수는 다음과 같이 호이스트됩니다.

 function getTotal(){
            let total;
            var multiplier;
            total = 0;
            for(var i = 0; i<10; i++){
                let valueToAdd;
                valueToAdd = i;
                multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

0

ES5 : 기능 호이 스팅 및 가변 호이 스팅

function hoisting우선 순위는 greater보다variable hoisting

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2016-06-01
 * @modified
 *
 * @description function-hoisting.js
 * @augments
 * @example
 * @link
 *
 */

(function() {
  const log = console.log;

  var a = 1;
  function b() {
    a = 10;
    log(`local a`, a)
    return;
    // function hoisting priority is greater than variable hoisting
    function a() {}
  }
  b();
  log(`global a`, a);
  // local a 10
  // global a 1
})();



이는

(function() {
  const log = console.log;

  // define "a" in global scope
  var a = 1;
  function b() {
    // define "a" in local scope
    var a ;
    // assign function to a
    a = function () {};
    // overwrites local variable "a"
    a = 10;
    log(`local a`, a);
    return;
  }

  b();
  // log global variable "a"
  log(`global a`, a);

  // local a 10
  // global a 1
})();

게양의 이유

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined

/**
 *  scpope & closure & hoisting (var/function)
 *  
 * 1. scpope : the global var can be access in any place(the whole file scope), local var only can be accessed by the local scope(function/block scope)!
 * Note: if a local variable not using var keywords in a function, it will become a global variable!
 * 
 * 2. closure : a function inner the other function, which can access local scope(parent function) & global scope, howerver it's vars can't be accessed by others! unless, your return it as return value!
 * 
 * 3. hoisting : move all declare/undeclare vars/function to the scope top, than assign the value or null!
 * Note: it just move the declare, not move the value!
 * 
 */

ES6 let, const호이 스팅 존재 없음

(() => {
  const log = console.log;
  log(a)
  // Error: Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 1;
})();



(() => {
  const log = console.log;
  log(b)
  // Error: Uncaught ReferenceError: Cannot access 'b' before initialization
  const b = 1;
})();

심판

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.