향상이란 무엇인지, 그리고 JavaScript에서 어떻게 작동하는지

15028 단어
최초 발표thejs.devhttps://thejs.dev/jmitchell/what-is-hoisting-and-how-it-works-in-javascript-e1e
이 유명하고 자주 곤혹스러운 용어는 어떤 자바스크립트 개발자에게도 그렇고 많은 사람들로 하여금 머리를 긁게 한다.승진은 도대체 뭐야?
향상은 JavaScript에서 선언에 대한 초기 액세스를 제공하는 메커니즘을 설명하는 용어입니다.

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.


자바스크립트에서 변수와 함수가 성명되기 전에 왜 상호작용을 할 수 있는지 생각해 본 적이 있습니까?그럼 계속 읽어주세요!

tl;박사 01 명
개념적으로 향상은 성명(변수와 함수)을 그 작용역의 맨 위로 이동하고 값을 보존하는 것이다.진정으로 발생하는 일은 컴파일할 때, 성명은 먼저 메모리에 넣지만, 코드에는 물리적으로 변하지 않는다는 것이다.
이렇게 하면 함수와 변수가 코드에 성명되기 전에 접근할 수 있다는 장점이 있다.이것은 성명에만 적용되고 표현식에 적용되지 않으며, 성명되지 않은 변수를 초기화하는 데도 적용되지 않는다.
foo("bar");
function foo(bar) {
  // do something
}
컴파일할 때 성명만 메모리로 올라가는 것이지 값을 부여하는 것이 아니라는 것을 기억하는 것이 중요하다.

선언만 걸기
JavaScript는 컴파일하는 동안에만 함수와 변수의 선언을 값이 아닌 메모리로 올립니다.이것은 변수를 사용한 후에 이 변수를 설명하고 초기화하면 이 값은 undefined이 된다는 것을 의미한다.
console.log(foo) // prints 'undefined' as only the _declaration_ was hoisted
var foo; // declaration
foo = "bar"; // initialization
다음은 반환ReferenceError의 초기화 예입니다.이런 상황에서 하나의 변수는 단지 초기화된 것이지 성명된 것이 아니다.JavaScript에서 올리려는 내용을 선언하려면 암시적 선언(초기화만 해당)이 올리지 않으므로 명시적으로 a var or function로 선언해야 합니다.
console.log(foo); // prints 'ReferenceError: foo is not defined'
foo = "bar"; // only initialization, no declaration, value did not follow var
중요한 것은 값을 지정해도 성명만 걸어 놓는다는 것을 기억해야 한다.
console.log(foo); // prints 'undefined'
var foo = "bar";

변수 올리기
JavaScript에서는 변수를 선언하고 초기화할 수 있습니다.그러나 엔진은 변수의 성명과 초기화를 분리하고 이를 단독 절차로 실행하여 엔진이 성명을 초기화 위로 끌어올릴 수 있도록 한다.
모든 함수와 변수 성명은 그 작용역의 맨 위로 올라가고 변수 성명은 함수 성명 전에 처리된다.이것이 바로 성명되지 않은 변수를 사용하여 함수를 호출할 수 있는 이유입니다. undefined 오류가 발생했습니다.
하지만 경고가 하나 있다.성명되지 않은 변수를 초기화할 때, 변수는 실행할 때 전체 범위로 올라가며, 함수를 초기화하는 것처럼 전체 범위로 올라가지 않습니다.이것은 번역할 때가 아니라 실행할 때만 발생한다.
function doSomething() {
  doing = "something";
}

console.log(doing); // ReferenceError: doing is not defined
doSomething();
console.log(doing); // something
이것은 작용역 변수 성명과는 달리 후자는 그 작용역 내에만 존재한다.
function doSomething() {
  var doing = "something";
}

console.log(doing); // ReferenceError: doing is not defined
doSomething();
console.log(doing); // ReferenceError: doing is not defined
주의해야 할 것은 성명된 변수는 컴파일할 때 그 역할 영역의 맨 위로 올라가고, 성명되지 않은 변수는 실행 기간에 전역 역할 영역으로 보존된다는 것이다.

사용letconst 선언은 글로벌 공간으로 확장되지 않습니다.letconst는 ES6에서 범위 기반의 조작을 도입하였으나 var와 달리 컴파일할 때 전역 공간으로 향상되지 않았다.let로 성명된 변수는 함수 범위가 아니라 블록 범위이다.var와는 달리 집행 범위 외에 변수 유출 위험이 없기 때문이다.
단점은 constlet가 현지나 전 세계에서 향상되지 않는다는 것이다.var, const and let에 대한 더 많은 정보를 읽으십시오.
console.log(foo); // prints 'ReferenceError: foo is not defined'
const foo = "bar";

console.log(bar); // prints 'ReferenceError: bar is not defined'
let bar = "bar";

엄격한 패턴이 느슨한 샹들리에를 방지했다
ES5에서 유틸리티로 도입strict-mode은 자바스크립트 제한 변형을 추가하는 방법을 선택하고 은밀하게 종료sloppy mode를 선택하는 방법이다.그것은 소리 없는 오류를 없애고 최적화를 개선했으며 변수를 설명하기 전에 접근하는 등 서로 다른 의미를 도입했다.
코드를 선언하기 전에 파일과 미리 대면하거나 역할 영역 상단에서 사용use strict을 선택하여 엄격한 모드로 전환할 수 있습니다.
'use strict';
// or
"use strict";
엄격한 모드가 설정된 경우 사전 액세스 초기화가 가능한지 테스트할 수 있습니다.
"use strict";
function doSomething() {
  foo = 20;
}
doSomething();
console.log(foo); // prints 'ReferenceError: foo is not defined'

모든 기능이 다 같은 것은 아니다
함수는 함수 성명이나 함수 표현식으로 나뉜다.조립에 대해 토론할 때, 둘 사이의 중요한 차이는 성명에 있다.성명된 함수는 향상되고 표현식으로 만든 함수는 향상되지 않습니다.
console.log(typeof hoistedFunction); // prints 'function'
console.log(typeof unhoistedFunction); // prints 'undefined'

function hoistedFunction() {
  // This function _will_ hoisted, because it is *declared* as a function
}

var unhoistedFunction = function() {
  // This function _will not_ be hoisted because it is declared through an expression of a variable, and therefore will be undefined 
}

순서
프로모션 함수와 변수를 사용할 때는 다음 두 가지 규칙을 기억해야 합니다.
  • 함수 성명이 변수 성명보다 우선
  • 변수 부여가 표현식 함수보다 우선
  • console.log(typeof myVar); // prints 'undefined'
    console.log(typeof myFunc); // prints 'function'
    var myVar = "foo"; // declaration and initialization
    function myFunc(){} // declaration
    console.log(typeof myVar); // prints 'string'
    
    우리는 컴파일링과 실행 주기 중의 절차를 더욱 깊이 있게 이해하고 우리의 성명과 초기화에 무슨 일이 일어났는지 볼 수 있다.
    function myFunc(){...}
    var myVar;
    console.log(typeof myVar);
    console.log(typeof myFunc);
    myVar = "foo";
    console.log(typeof myVar);
    

    수업 시간은 멈추지 않는다
    JavaScript의 클래스는 실제로 특수한 함수입니다. 성명과 표현식으로 함수를 정의할 수 있는 것처럼 클래스 문법에는 두 개의 같은 구성 요소가 있습니다. class expressions and class declarations
    함수와 변수와 달리 클래스는 성명이나 표현식을 통해 향상되지 않습니다.너는 먼저 너의 종류를 성명한 후에야 그것을 사용할 수 있다.
    const p = new Rectangle(); // ReferenceError
    console.log(typeof Rectangle); // ReferenceError
    
    class Rectangle {}
    

    결론
    지금까지 배운 내용을 요약해 보겠습니다.
  • 향상은 주어진 실행 범위
  • 에서 값을 부여하고 초기화하기 전에 변수와 함수 성명을 메모리에 삽입하는 메커니즘이다.
  • const, let, 함수 표현식과 클래스가 향상되지 않으며, 성명
  • 하기 전에 읽히거나 접근할 수 없습니다.
  • safe-mode 초기화된 선언되지 않은 변수를 임의로 전역 범위로 끌어올리는 것을 방지한다
  • 장기적인 혼란과 문제를 피하기 위해서는 초기화와 방문을 하기 전에 변수와 함수를 설명하는 것이 좋다.너는 잠재적으로 싫어하는 오류와 undefined 경고가 너의 컨트롤러를 오염시키는 것을 피할 것이다.

    좋은 웹페이지 즐겨찾기