호이스팅 (Hoisting)

호이스팅이란 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것이다.

오해가 있을 수 있는 부분인데, 실제로 코드가 끌어올려지는 것은 아니며, javascript Parser 내부적으로 컴파일 단계에서 끌어올려 처리하는 것이다.

catName('Chloe');

function catName(name) {
    console.log("My cat's name is " + name);
}

위 코드에서 함수를 작성하기 전에 함수를 호출하였지만, 코드는 정상적으로 작동한다.

var 변수 선언함수선언문에서만 호이스팅이 일어난다.
var foo2 = function(){...} 형식의 함수표현식let/const 변수 선언에서는 호이스팅이 발생하지 않는다.

var 변수/함수의 초기화(할당)가 아닌 선언만 끌어올린다. 변수를 선언한 뒤에 나중에 초기화시켜서 사용한다면, 그 값은 아래 예시와 같이 undefined로 지정된다.

var x = 1; // Initialize x
var y; // Declare y
console.log(x + ' ' + y); // '1 undefined'
y = 2; // Initialize y

코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않게 해야하며, let/const 를 사용함으로써 이 문제를 방지할 수 있다.

ES6를 모든 브라우저가 지원하는 것이 아니므로, ES5로 babel 등을 통해 트랜스컴파일을 진행해야 하고 이것이 var의 동작에 대해 FE 개발자가 이해하고 있어야 하는 이유이다.

Reference

'Language > JavaScript' 카테고리의 다른 글

자바스크립트 Primitive(원시값)  (0) 2020.06.13
자바스크립트 클로저  (0) 2020.06.12
CORS  (0) 2020.05.04
SPA란  (0) 2020.01.07

Primitive

Javascript에서 원시값(primitive, 원시 자료형)이란 객체도 아니고 메서드도 아닌 data이다.
총 7개의 원시 자료형이 존재한다.

  • string
  • number
  • bigint
  • boolean
  • null
  • undefined
  • symbol (ES16에서 추가)

모든 primitive는 불변이다. primitive 자체와 primitive을 할당한 변수를 혼동하지 않아야 한다. 변수는 새로운 값을 다시 할당할 수 있지만, 이미 생성한 primitive는 객체, 배열, 함수와 달리 변형이 불가하다. 여기서 객체, 배열, 함수를 원시값과 구별하여 참조 타입(reference type) 이라고 부른다.

var numberPrimitive = 10;
var booleanPrimitive = false;
var stringPrimitivie = 'string boy';

위 코드에서 예를 들어 설명을 하자면, 대입되는 오른쪽 값이 primitive로 보면 되고, 실제 작동할 때는 변수를 이용하여 작업을 한다. 원시값이 변하지 않는 이유는, 원시값에 직접 작업하는 것이 아니라, 원본을 건드리지 않고 복사본을 가져와 작업을 하는 것이기 때문.

  • 각각의 값은 모두 스택에 저장된다
  • 변수 자체가 하나의 값을 가진다.
  • 인자가 전달될 때 call by value의 형태로 넘어간다.
  • primitive type의 값은 immutable하다.

null과 undefined를 제외하고, 모든 primitive는 원시값을 래핑한 객체를 가진다.

  • 문자열 원시값을 위한 String 객체
  • 숫자 원시값을 위한 Number 객체
  • 빅인트 원시값을 위한 BigInt 객체
  • 불리언 원시값을 위한 Boolean 객체
  • 심볼 원시값을 위한 Symbol 객체

Reference

'Language > JavaScript' 카테고리의 다른 글

호이스팅 (Hoisting)  (0) 2020.06.14
자바스크립트 클로저  (0) 2020.06.12
CORS  (0) 2020.05.04
SPA란  (0) 2020.01.07

클로저(Closure)

클로저는 함수의 실행이 끝난 뒤에도 함수에 선언된 변수의 값을 접근할 수 있는 자바스크립트의 성질이다. 바로 예시로 들어가보자.

function addCounter() {
    var counter = 0;

    return function () {
        return counter++;
    };
}

addCounter();
console.log(counter);

위 코드는 오류가 나는 코드이다. addCounter() 함수의 실행이 끝난 시점에서 counter라는 변수는 더이상 접근을 할 수 없는 상태이다. 함수 안에 선언한 변수는 함수 안에서만 유효 범위를 갖기 때문이다.

function addCounter() {
    var counter = 0;

    return function () {
        return counter++;
    };
}

var add = addCounter();
add();
add();
add();

아까와는 달리 이 코드는 오류 없이 실행된다. addCounter() 함수가 반환한 함수를 add라는 변수에 담아놓았기 때문에 add 자체가 함수처럼 동작하는 것이다.

addCounter()의 반환 함수는 자신이 생성된 렉시컬 스코프에서 벗어나 global에서 add라는 이름으로 호출이 되었다. 이런 add 와 같은 함수를 클로저라고 부른다.

addCounter() 의 렉시컬 스코프에서 생성된 instance는 addCounter(); 수행이 끝난 후에 Garbage Collector가 회수해야 하는데, 사실은 그렇게 작동하지 않는다. 위에서 설명한 것과 같이, addCounter()의 반환 함수는 렉시컬 환경인 addCounter()의 렉시컬 환경을 계속 참조하고 있고, global에서 add가 해당 함수를 계속 참조하고 있기 때문이다. 이 때문에 클로저를 남용하게 되면 메모리 이슈가 생기게 된다.

클로저를 응용하여 자바스크립트에 없는 private 변수를 구현할 수 있다.

function counter() {
    var _count = 0;

    return function () {
        _count += 1;

        return _count;
    };
}
var counterFirst = counter();
console.log(counterFirst());
console.log(counterFirst());

위와 같이 구현하면, _count 변수는 외부에서 접근할 수 없는 방법이 없다. counter() 함수 내에서만 접근할 수 있는 private 변수가 구현된 것이다.

Reference

'Language > JavaScript' 카테고리의 다른 글

호이스팅 (Hoisting)  (0) 2020.06.14
자바스크립트 Primitive(원시값)  (0) 2020.06.13
CORS  (0) 2020.05.04
SPA란  (0) 2020.01.07

 

 

'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

네이버 캠퍼스 핵데이 시작이 얼마 안 남았는데 기술 부채로 인한 문제가 심각하다.. 

대주제는 정해졌지만 소주제는 자유로 적혀 있어서 네이버 Open api를 사용하는 주제를 개인적으로 해보려고 했고,

프로젝트가 시작되기 전에 Vue.js를 써서 lean하게 구현해보려고 했는데, axios로 api를 호출하는 것에서 CORS 정책으로 인해 막혔다.

네이버 api는 타 사용자의 client id와 client secret 를 도용하여 api를 호출하는 것을 막기 위해 서버 프로그래밍을 통해서만 호출하도록 되어 있다.  으악

(https://developers.naver.com/forum/posts/26989)

 

그런데 프로젝트의 선택 요구사항에 nodejs server framework (express, koa) 혹은 serverless 구성을 택할 것으로 적혀있다.

말그대로 선택사항이라 지킬 필요는 없으나 이왕이면 다홍치마 아니겠는가.

문제는 나한테 서버는 django가 익숙하고, serverless라면 AWS Lambda 같은 것을 얘기하는 것 같은데, 전혀 경험이 없다.

 

방법은 다음 중에 택하면 될 듯하다.

  1. nodejs 서버 프레임워크를 공부한다. 커뮤니티는 express가 크고, koa는 기업 종속성이 낮아 미래가 밝다는 것 같다. 이 방안이라면 더 빠른 구현이 가능한 것을 택할 듯.

  2. AWS Lambda나 firebase에서 함수 기반으로 해결이 가능하다면 해당 플랫폼 사용.

  3. axios.get 의 경우에,  JSONP 이라는 것으로 해결이 된다는 얘기가 있어 가장 우선적으로 시도해볼 것임 -> html 문서의 script 태그는 보안정책에 적용되지 않는 점을 이용한 것 -> (05.15 추가) 서버 측에서 JSONP 형식을 지원해야 하는 단점이 있어 범용적으로 사용하기 어렵다.

  4. 프록시? -> (05.15 추가) 1번과 동일한 방법. 프록시 서버를 구축하는 것.

 

해커톤 시작되기 전에 빨리 공부해야지..

 

(참고: https://velog.io/@takeknowledge/%EB%A1%9C%EC%BB%AC%EC%97%90%EC%84%9C-CORS-policy-%EA%B4%80%EB%A0%A8-%EC%97%90%EB%9F%AC%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-3gk4gyhreu)

'Language > JavaScript' 카테고리의 다른 글

호이스팅 (Hoisting)  (0) 2020.06.14
자바스크립트 Primitive(원시값)  (0) 2020.06.13
자바스크립트 클로저  (0) 2020.06.12
SPA란  (0) 2020.01.07

 

 

SPA란 Single Page Application의 약자로,

대표적인 라이브러리/프레임워크로 Angular, React, Vue가 있다. 

 

기존 방식과는 다르게 SPA는 페이지를 처음 한번만 로드하고, 이후 필요한 부분만 AJAX (Asynchronous Javascript And Xml) 을 이용하여 데이터를 binding한다. 

 

Vue나 React 같은 프레임워크가 궁극적으로 추구하는 목적은 

백엔드 개발 트렌드인 MVC 패턴에서 

View를 아예 분리해 하나의 Application으로 만들고

백엔드는 api형태로 동작하는 것이다.

 

 

'Language > JavaScript' 카테고리의 다른 글

호이스팅 (Hoisting)  (0) 2020.06.14
자바스크립트 Primitive(원시값)  (0) 2020.06.13
자바스크립트 클로저  (0) 2020.06.12
CORS  (0) 2020.05.04

+ Recent posts