var, let, const의 차이
var
, let
, const
는 모두 JavaScript에서 변수를 선언하는 방법이지만 각각의 차이점이 있습니다.var
: 예전부터 있었던 변수 선언 방식으로, 변수의 스코프(scope)가 함수 레벨(function-level)입니다. 즉, 함수 내부에서 선언한 변수는 해당 함수 내부에서만 유효하며, 함수 외부에서 선언한 변수는 전역 범위(global scope)에서 유효합니다. 또한,var
는 선언 시 초기값을 주지 않아도 됩니다.
let
: ES6에서 추가된 변수 선언 방식으로, 변수의 스코프가 블록 레벨(block-level)입니다. 즉, 중괄호({}
)로 둘러싸인 코드 블록 내에서 선언한 변수는 해당 블록 내부에서만 유효하며, 블록 외부에서 선언한 변수는 전역 범위에서 유효합니다.let
은 선언 시 초기값을 주지 않아도 됩니다.
const
:const
는let
과 동일한 블록 레벨 스코프를 가지며, 재할당이 불가능한 상수(constant)를 선언할 때 사용합니다. 즉, 변수를 선언할 때 반드시 초기값을 지정해야 하며, 이후에는 재할당이 불가능합니다. 단, 객체나 배열과 같은 자료형은 참조형 변수로써 내부 값은 변경할 수 있지만 변수 자체를 다른 값으로 재할당할 수 없습니다.
스코프란 무엇인가요?
자바스크립트의 스코프는 변수, 함수 및 객체 등의 식별자(identifier)가 유효한 범위(scope)를 말합니다. 스코프는 변수나 함수가 선언된 위치에 따라 결정됩니다.
스코프는 전역 스코프(global scope)와 지역 스코프(local scope)로 나뉩니다. 전역 스코프는 어떤 함수나 블록 안에 속하지 않은 최상위 스코프를 말합니다. 전역 스코프에서 선언된 변수는 어디서든지 접근할 수 있습니다.
지역 스코프는 어떤 함수나 블록 안에 선언된 스코프를 말합니다. 함수 안에서 선언된 변수는 해당 함수의 지역 스코프에서만 유효하며, 함수 밖에서는 접근할 수 없습니다. 함수스코프와 블록 스코프로 나눠지고 블록 스코프는 ES6에서 추가된 let과 const 키워드를 사용하여 만들 수 있습니다.
함수가 중첩된 경우, 내부 함수는 외부 함수의 스코프를 계속해서 참조할 수 있습니다. 이를 클로저(closure)라고 합니다.
스코프는 변수나 함수 등의 식별자가 유효한 범위를 결정하기 때문에, 변수나 함수의 이름이 충돌하는 것을 방지하고 코드를 더욱 안정적으로 만들어줍니다. 스코프 정보는 현재 실행중인 실행 컨텍스트 안에서 연결 리스트와 유사한 형식으로 만들어지는데 이 리스트를 스코프 체인(scope chain)이라고도 부릅니다.
클로저란 무엇이며, 어떻게 사용될 수 있나요?
클로저란 이미 라이프 사이클이 종료된 외부 함수에서 생성한 식별자에 내부 함수가 접근할 수 있는 특성으로 외부 함수 밖에서 내부 함수가 호출되더라도 스코프 체인을 통해 식별자를 참조할 수 있는 것을 의미합니다.
이를 통해 외부에서 접근, 수정이 불가하도록 정보 은닉이 가능하고 전역 변수의 사용을 억제해서 충돌을 방지할 수 있습니다. 단점으로는 메모리 낭비가 일어날 수 있다는 점이 있습니다.
함수와 메서드의 차이는 무엇인가요?
함수는 일반적으로 독립적으로 존재하고 호출될 때 인자를 전달하고 결과값을 반환합니다. 그리고 전역 또는 다른 함수 내부에서 선언될 수 있습니다.
반면에 매서드는 객체의 프로퍼티로서 정의된 함수를 의미합니다. 객체 내부의 함수를 매서드라고 부르며, 객체의 상태를 참조하거나 변경하는 용도로 사용됩니다.
함수와 매서드의 가장 큰 차이점은 호출 방법과 사용되는 컨텍스트입니다. 함수는 전역에서 호출 될 수 있고 호출되는 방법이 일관적이지만 매서드는 객체에 종속되어 해당 객체의 상태와 속성에 접근할 수 있습니다.
프로토타입 상속이란 무엇이며, 어떻게 작동하나요?
자바스크립트의 객체는 다른 객체를 상속하는 특성이 있어서 상위 객체의 프로퍼티와 매서드를 사용할 수 있습니다. 생성자 함수로 생성된 객체에 prototype 프로퍼티로 객체를 생성하여 상속된 내용들을 사용할 수 있습니다. 이를 통해 객체간 코드 재사용을 촉진할 수 있습니다.
동기적 코드와 비동기적 코드의 차이는 무엇인가요?
두 개념은 코드 실행 순서에 대한 차이점이 있습니다. 동기적 코드는 위에서 아래로 순서대로 실행되고 한 줄의 코드 실행이 끝나야 다음 줄의 코드가 실행됩니다. 그렇기에 순서 예측이 가능하여 결과를 쉽게 예측할 수 있습니다.
반면에 비동기적 코드는 코드가 실행되는 동안 다른 코드도 실행될 수 있습니다. 대표적인 예로는 setTiemout 함수입니다. 자바스크립트에서는 콜백 함수나 promise, async/await 등을 비동기를 처리하는 방식을 사용합니다.
promise.all, promise.race?
여러 비동기작업들을 동시에 처리하고, 작업이 실행 완료되면 모두 다 반환하는 매서드이다.
race메서드는 실행이 가장 빠른 결과 하나를 반환합니다.
콜백 함수란 무엇이며, 어떻게 사용될 수 있나요?
함수의 인자로 다른 함수가 전달되어 실행되는 함수입니다. 대표적인 예로는 setTimeout 함수로 일정 시간이 지난 후 전달된 함수를 실행시키는 함수입니다. 그리고 이벤트 처리가 있습니다. addeventListener로 특정 이벤트나 조건이 발생했을 때 실행되도록하여 비동기적인 상황에서 많이 사용됩니다 또한 코드를 보다 간결하게 작성할 수 있습니다.
하지만 비동기적인 작업을 콜백으로만 해결하려다 보면 뎁스가 점점 깊어져 소위 콜백 지옥이라고 불리는 형태로 가독성이 떨어지는 코드가 작성될 수 있다는 문제점도 있습니다.
Promise란 무엇이며, 어떻게 사용될 수 있나요?
ES6에서 콜백이 가지던 문제인 예외 처리가 어렵다는 점과 중첩으로 복잡도가 증가하는 문제를 해결하기 위해 출현하였습니다.
promise는 비동기적인 작업을 다룰때 사용되는 객체입니다. 작업이 완료되었을 때 결과값을 반환하거나 에러를 처리하는 등의 기능을 제공합니다.
3가지 상태 pending, fullfilled, rejected를 가지고
new Promise()를 통해 객체를 생성할 수 있고 resolve, reject 콜백 함수를 전달해서 fullfilled와 Rejected 상태를 처리할 수 있습니다.
또한 then, catch, finally와 같은 메서드들을 체이닝을 통해 연결하여 앞서 언급했던 예외 처리와 중첩문제를 해결할 수 있습니다.
async/await란 무엇이며, 어떻게 사용될 수 있나요?
promise의 then을 연쇄적으로 체이닝하면 이전 콜백의 중첩 문제처럼 혼란스러운 코드를 작성할 수 있다는 문제점을 해결하기 위해 ES8에서 도입되었습니다.
함수에 async를 선언해주고 await에 Promise 객체를 전달하여 동기적으로 처리되는 것처럼 작성할 수 있습니다. async는 항상 promise 객체를 반환합니다. 그리고 try-catch문을 활용해서 에러 처리를 쉽게 작성할 수 있다는 장점이 있습니다.
이벤트 루프란 무엇이며, 어떻게 작동하나요?
자바스크립트는 단일 스레드를 기반으로 동작합니다. 단일 쓰레드는 한번에 하나의 작업만 가능하지만 비동기 처리와 같은 내용은 멀티 쓰레드처럼 동작합니다 이는 브라우저의 이벤트 루프를 통해 동작한다. 자바스크립트 엔진은 크게 콜스택, 웹 API, 태스크 큐로 나눠집니다.
동기적인 작업은 콜스택에 한가지 작업이 쌓이고 작업이 완료되면 제거후 다음 작업을 콜스택에 추가합니다.
하지만 비동기 작업의 경우 콜스택에 추가되었다가 비동기작업임을 확인하고 웹 api로 이동되어 처리가 이뤄지고 이후 태스크 큐로 이동하여 콜스택이 비워질때까지 대기합니다. 그리고 콜스택으로 들어가 실행되게 됩니다.
태스크 큐에는 microtask queue, animation frames ,macrotask queue와 같이 우선순위를 부여해 어떤 작업을 먼저 수행할지 결정하여 콜스택에 추가합니다.
microtask는 promise, async/await와 같은 내용들을 처리하고 macrotask는 setTimeout, setInterval과 같은 함수들을 처리합니다. animation frames는 request animation frame과 같은 브라우저 렌더링 관련 작업을 받는 queue입니다. microtask queue, animationframes, macrotask queue를 우선 순위가 선정됩니다.
hoisting이란 무엇이며, 어떻게 작동하나요?
실행 컨텍스트 생성 시 렉시컬 스코프 내의 선언이 끌어올려 지는 현상으로 식별자는 자바스크립트 코드 평가 단계에서 메모리 공간을 선언 전에 미리 할당하는 특징 때문에 발생됩니다.
호이스팅이란 자바스크립트 var 변수와 함수를 인터프리터 코드 상단으로 끌어올리는 것 같은 현상으로
자바스크립트 엔진이 코드 컴파일 과정에서 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var 변수는 선언하기 이전 코드에서 호출이 일어나면 undefined를 출력합니다 그 이유는 호이스팅시 Undefined로 변수를 초기화하기 때문입니다. 함수의 경우에는 순서에 상관없이 정상 작동합니다.
var의 이러한 문제 때문에 let과 const를 사용하는 것이 권장됩니다. 이 두가지도 호이스팅의 대상이지만 undefined로 변수를 초기화하지 않습니다. let의 경우에는 TDZ으로 reference error가 발생합니다.
strict mode란 무엇이며, 어떻게 사용될 수 있나요?
'strict mode(엄격 모드)'는 자바스크립트에서 도입된 기능으로, 코드를 더욱 안전하고 명확하게 만들어주는 역할을 합니다. strict mode를 사용하면 기존의 자바스크립트 문법에서 예외적인 상황에서도 오류가 발생하도록 하여, 더욱 엄격한 검사를 수행하게 됩니다.
strict mode는 다음과 같은 기능을 제공합니다.
- 암묵적인 전역 변수의 생성 방지
- 변수, 함수 등의 중복 선언 방지
- with 문 사용 제한
- 삭제할 수 없는 속성 삭제 방지
- arguments 객체의 매개변수 값과 매개변수의 개수 일치 여부 검사 등
strict mode를 사용하려면, 스크립트 파일의 첫 줄에
'use strict';
를 선언하면 됩니다. 함수 단위로 strict mode를 적용하고자 한다면, 함수 내부에서 'use strict';
를 선언하면 됩니다.javascriptCopy code 'use strict'; function myFunction() { 'use strict'; // 함수 내용 }
strict mode는 코드를 더욱 안전하게 만들어주지만, 기존의 코드와 호환성이 떨어질 수 있으므로 주의해서 사용해야 합니다. 또한, strict mode는 자바스크립트 엔진의 최적화를 방해할 수 있기 때문에, 모든 코드에 적용하는 것이 좋지 않을 수 있습니다. 따라서 strict mode를 사용하기 전에는 충분한 테스트를 거쳐야 합니다.
변수 선언시 순서
선언 → 초기화 → 할당
자바스크립트 엔진은 소스코드 평가 과정에서 변수 선언문을 먼저 실행합니다. 이때 생성된 변수는 실행 컨텍스트가 관리하는 스코프에 등록되고 undefined로 초기화됩니다. 이후 소스코드가 실행되는 과정에서 할당이 이루어지게 됩니다.
실행 컨텍스트가 무엇인가요?
자바스크립트 변수, 함수, 클래스등의 식별자를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 매커니즘으로 모든 코드는 실행컨텍스트를 통해 실행되고 관리됩니다. 식별자와 스코프는 렉시컬 환경에서 관리하고 코드 실행 순서는 실행 컨텍스트 스택으로 관리되어집니다.
- 실행 컨텍스트 스택은 무엇인가요?
- 위에 언급했던 실행컨텍스트는 스택 자료구조로 관리됩니다. 코드의 평가와 실행을 스택 형태로 처리하기 때문에 코드 실행 순서를 관리합니다.
- 렉시컬 환경은 무엇인가요?
- 렉시컬 환경은 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트입니다. 렉시컬 환경은 두개의 컴포넌트로 구분됩니다. 하나는 환경레코드로 식별자와 실별자에 바인딩된 값을 관리하는 저장소이고 또 다른 하나는 외부렉시컬 환경에 대한 참조(Outer lexicalEnvironmentRefrence)는 상위 스코프를 참조할 수 있도록해줍니다.
화살표 함수와 일반함수의 차이를 설명해보세요.
일반함수와 화살표함수는 3가지 차이점을 가지고 있습니다.
- 화살표 함수는 인스턴스를 생성할 수 없습니다. 그렇기 때문에 생성자 함수로 사용할 수 없고 prototype 프로퍼티가 없습니다.
- 중복된 매개변수 이름을 선언할 수 없습니다. 일반 함수에서는 중복된 매개변수 이름을 선언해도 에러가 발생하지 않습니다.
- 마지막으로 화살표 함수는 함수 자체의 this, super등의 바인딩을 갖지 않습니다. 그렇기 때문에 화살표 함수 내부에서 this 참조를 하면 스코프 체인을 통해 상위 스코프의 this를 참조합니다.
- 화살표 함수가 중첩되어 있어도 화살표함수가 아닌 함수의 this를 참조한다.
프로퍼티와 어트리뷰트에 차이점은 뭔가요?
어트리뷰트는 HTML 마크업에 정의되나 프로퍼티 DOM에 정의되어집니다.
Undefined와 Null을 구별하는 것은 무엇입니까?
undefined는 아직 값이 지정되지 않은 선언된 변수이고 null은 할당 값입니다.
자바스크립트를 동적타입 언어라고 부르는 이유는?
정적 타입은 언어는 변수를 선언할 때 변수에 할당할 수 있는 값 데이터 타입을 사전에 선언해야하지만,
자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정됩니다. 타입 추론이 가능한 것이고, 재할당에 의해 변수의 타입을 언제든지 동적으로 변경할 수 있습니다.
This란 무엇인가요?
자바스크립트의 객체는 데이터와 함수로 이루어지는데 여기서 this 키워드는 함수가 자신이 속한 객체의 데이터를 참조하려면 자신이 속한 객체를 참조할 수 있도록 하기 위함입니다
this는 함수가 어떻게 호출되었는지에 따라 동적으로 결정이 됩니다.
일반함수의 this는 전역으로 바인딩, 매서드 내부의 This는 매서드를 호출한 객체에, 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가르킵니다.
즉시실행함수
IIFE, Immediately Invoked Function Expression 즉시실행 함수는 정의되자마자 즉시 실행되는 함수로
함수 선언문을 괄호로 감싸고 그 뒤에 ()로 실행하여 동작합니다. 익명함수로 작성되는것이 보편적인데 그 이유는 재사용이 불가능하기 때문입니다. 또한 즉시 실행 함수를 사용하는 이유는 필요없는 전역 변수의 생성을 줄일 수 있고, Private한 변수를 만들어 외부 접근을 막을 수 있습니다.
이터러블
이터러블은 순회가 가능한 데이터를 말합니다. Es6 이전에는 다양한 방법으로 순회를 할 수 있었으나 Es6 이후로는 For of문으로 순회가 가능한 데이터를 이터러블이라고 말합니다.
- 어떤 데이터들이 이터러블인가?
- 배열, 문자열, Map, Set은 이터러블입니다. 이 데이터 컬렉션은 symbol.iterator을 프로퍼티 키로 상속받은 객체입니다.
Symbol에 대해서 알고 계신가요?
네, 심볼은 ES6에서 도입된 7번째 데이터 타입으로 다른값과 중복되지 않는 유일한 값입니다. 주로 프로퍼티 키로 사용하고 중복되지 않기 때문에 충돌의 위험이 없는 장점이 있습니다.
명령형 프로그래밍과 선언형 프로그래밍의 차이접
명령형은 무엇을 어떻게 할 것인가에 포커스를 두고 예시로는 For문이 있습니다. 선언형 프로그래밍은 무엇을 할것인가에 포커스를 두고 Reduce. map을 예로 들 수 있습니다.