hoisting이란 변수, 함수 선언을 최상단으로 끌어 올린다는 것이다. 즉 런타임시 어떤 변수를 출력하는데 변수선언이 되어있지 않음에도 불구하고 오류가 나지 않는다는 것이다. 예를 들어보자

 

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

 

위의 경우 변수 a를 선언하기도 전에 콘솔 창에 a를 출력하도록 했다. 원래대로라면 오류가 나야 정상이지만 자바스크립트에서 var 로 변수를 선언하게 되면 hoisting이라는 특성 때문에 오류가 나지않는다 즉, 최상단에서 변수선언이 이루어 진 것이다. 때문에 변수 선언문 다음의 콘솔출력은 정상적으로 1이 출력되는 것을 볼 수 있다.

이러한 hoisting은 다른언어를 공부한 사람들에게는 정말 미친(?) 개념이 아닐 수 없다. 이러한 오류를 줄이기 위해 변수 선언시 let을 사용하는 것이 좋다.

이러한 hoisting은 var에서 일어나는 현상이다.

 

console.log(a);
let a = 1;
console.log(a);

같은 코드에서 변수선언을 let으로 해보았다. 콘솔창에서 오류가 발생하는 것을 알 수 있다. 이것이 정상적인 것이다...

let은 ES6에서 추가가 되었는데 chrome에서는 호환이 잘 되기 때문에 문제없이 사용가능하다.

문제많은 var를 사용할 이유가 없다.

 

또 var를 사용하면 안되는 이유가 있다.

{ }스코프에 영향을 받지 않는다. (이것도 정말 미친것같다...)

 

{
    var a = 1;    
}
console.log(a);

위 코드를 보면 변수 a는 스코프 안에서 var를 통해 선언되었고 1을 할당 받았다. 그리고 스코프 밖에서 a를 출력한다. 정상적이라면 오류가 나야 정상이다. 하지만..

이렇게 스코프를 무시하고 1을 출력하는 것을 볼 수 있다. (정말 문제가 많은 녀석이다...)

하지만 let을 사용하면 

{
    let a = 1;    
}
console.log(a);

이렇게 정상적으로 오류가 나는 것을 볼 수 있다. (이게 지극히 정상이다..)

 

결론 : 변수선언시 let을 사용하는 것이 바람직하다 

반응형

순수 바닐라 자바스크립트를 사용할땐 use strict을 선언하는 것이 좋음

자바스크립트 언어는 굉장이 유연한 언어이다. 유연하다는 것은 아주 위험하기도 하다는 것이다. 

이는 개발자가 많은 실수를 할 수 있다는 것을 의미한다. 자바스크립트에서는 선언되지 않은 변수의 값을 할당 한다던지 아니면 기존에 존재하는 프로토타입을 변경한다든지 이런 비상식적인 것들은 다른언어를 공부하고 온 개발자들이 봤을 때 미친 것들이다... use strick는 ECMAScript5 에 추가되어 있다. 그래서 use strict를 선언하면 비상식적인 행위들을 할 수 없게된다. 즉 비상식적인 오류들을 줄일 수 있다는 것이다.

반응형

html로 자바스크립트를 불러올 때 여러가지 방법으로 코드를 가져올 수 있는데 asyn와 defer 속성을 사용하는 것이 이에 해당된다. asyn와 defer말고도 다른 가능한 경우들도 코드를 보면서 차근차근 설명해보겠다.

위 코드에는 html을 쭉 parsing 하다가 script tag가 보이면 main.js를 다운받는다. 이때 parsing을 잠시 멈추고 필요한 자바스크립트 파일을 서버에서 다운받아 실행한 다음에 parsing하는 부분으로 넘어간다 이때 단점은 js파일이 용량이 크면 속도에 많은 지장을 준다. 따라서 사용자의 속도가 느려진다. 이 때문에 script를 head에 넣는것은 좋은 습관이 아니다.

 

 

그리고 위코드처럼 body안 끝부분에 script를 추가하는 경우가 있는데 이 경우는 html을 다운받아 쭉 parsing하면서 페이지가 준비가 된 다음에 script를 만나게 되면 서버에서 script를 받아오고 실행하게 된다. 그래서 js를 받기도 전에 페이지가 사용자들에게 준비가 되면서 사용자가 페이지의 컨텐츠를 볼 수 있다. 이 방법은 사용자가 기본적인 html의 컨텐츠를 빨리 본다는 장점은 있지만 웹사이트가 자바스크립트에 의존적이라면 즉, 사용자가 의미있는 컨텐츠를 보기위해서 자바스크립트를 이용해서 서버에 있는 데이터를 받아와야하는 경우의 웹사이트라면 사용자가 정상적인 페이지를 보기전까지는 fetching하는, 그러니까 서버에서 자바스크립트를 받아오는 시간을 기다려야되고 실행하는 시간도 기다려야하는 단점이 있다.

 

 

그리고 위의 경우는 head안에 script를 이용하되 asyn라는 속성값을 사용하는 것이다. asyn는 boolean타입의 속성값이기 때문에 이렇게 선언하는 것만으로도 true로 설정이되어 asyn옵션을 사용가능하다. asyn를 사용하면 브라우저가 html을 다운받아 parsing 하다가 asyn를 발견하면 병렬로 main.js를 다운받으라는 명령을 내려놓고 다시 parsing을 하다가 main.js가 다운완료되면 그때 parsing하는 것을 멈추고 다운로드된 js파일을 실행한다. 이렇게 실행하고 나서 나머지 html을 parsing한다. 

이 경우 body끝에 사용하는 것보다 fetching이 parsing하는 동안 병렬적으로 일어나기 때문에 다운로드 받는 시간을 절약할 수 있다. 하지만 자바스크립트가 html이 parsing 되기도 전에 실행이 되기때문에 만약 js파일에서 query selector를 이용해서 DOM요소를 조작하려 한다면 이 조작하려하는 시점에 html이 우리가 원하는 요소가 아직 정의 되어 있지 않을 수 있다. 이 부분이 조금 위험할 수 있다. html을 parsing하는 동안에 언제든지 js를 실행하기 위해서 멈춰질수 있기 때문에 사용자가 페이지를 보는데에 시간이 조금 걸릴 수 있는 단점이 있다.

 

 

이 경우는 defer을 사용하는 것이다. 앞에서와 마찬가지로 head안에 script를 넣고 정의하는데 이 경우는 parsing 하다가 script에 defer를 보고 main.js 다운 명령만 시켜놓고 나머지 html을 끝까지 parsing한다. 그리고 마지막에 parsing이 끝난 다음에 다운로드된 main.js를 실행한다. 때문에 defer를 사용하는 것이 가장 좋은 옵션이라고 할 수 있다.

html을 parsing하는 동안 js파일을 다운받아 놓고 html parsing을 먼저해서 사용자에게 페이지를 보여준 다음에 js를 실행하기 때문이다.

 

 

그리고 위의 경우는 asyn옵션으로 다수의 script를 다운받으면 먼저 다운되는 것을 먼저 실행되고 다음에 다운완료되는 것이 실행되기 때문에 순서에 의존적인 자바스크립트라면 문제가 될 수 있다.

 

 

위 코드와 같은 상황에서 defer같은 경우는 parsing하는 동안 필요한 script를 모두 다운받아 놓고 순서대로 실행하기 때문에 정리한 순서대로 실행이 된다.

 

 

* 종합해보면 가장 마지막 경우와 같이 head 안에 defer옵션을 이용해서 가장 효율적이고 안전하다고 볼 수 있다.

반응형

+ Recent posts