일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- pr review
- 제너레이터와 async/await
- 스코프
- 블로그 서비스 최적화
- 새 코드 받아오기
- 브라우저의 렌더링 과정
- const
- DOM
- 모던 자바스크립트 Deep Dive
- version management
- js pattern
- mixin pattern
- 이미지 갤러리 최적화
- peerdependencies
- 프론트엔드 성능 최적화 가이드
- 자바스크립트 패턴
- middleware pattern
- 자바스크립트
- 진행기록
- 커리어
- Babel과 Webpack
- js pattern
- 학습내용정리
- package management
- 이벤트
- 올림픽 통계 서비스 최적화
- 프로그래머스
- unique identifiers
- 자바스크립트 딥다이브
- 딥다이브
- Today
- Total
Dev Blog
3. Javascript 본문
1. Closure 에 대한 설명과 예시를 설명해주세요.
클로져는 "함수와 함수가 선언된 어휘적(lexical) 환경"의 조합을 말합니다.
이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성됩니다.
통상적으로 "외부함수의 변수에 접근할 수 있는 내부함수"를 클로져 함수라 부릅니다.
외부함수의 실행이 종료된 후에도, 클로져는 외부함수의 스코프를 참조할 수 있습니다.
클로저 사용 예시:
1) 커링: currying, 함수 하나가 n개의 인자를 받는 대신 n개의 함수를 만들어 각각 인자를 받게 하는 방법
2) 클로저 모듈: 변수를 외부 함수 스코프 안쪽에 감추어, 변수가 함수 밖에서 노출되는 것을 막는 방법) 등의 패턴을 구현할 수 있습니다.
예시 링크: nomadkim880901.tistory.com/266
클로저의 단점: 일반 함수였다면 함수 실행 종료 후 가비지 컬렉션(참고 자료: MDN '자바스크립트의 메모리 관리') 대상이 되었을 객체가, 클로저 패턴에서는 메모리 상에 남아 있게 됩니다. 외부 함수 스코프가 내부함수에 의해 언제든지 참조될 수 있기 때문입니다. 따라서 클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있습니다.
2. js에서 this란 무엇이고 어디에 사용되나요?
this는 함수 실행시 호출(invocation) 방법에 의해 결정되는 특별한 객체
패턴 | 바인딩되는 객체 | 설명 |
Method 호출; obj.foo() | 부모 객체 (실행 시점에 온점 왼쪽에 있는 객체) | 하나의 객체에 값과 연관된 메소드를 묶어서 사용할 때 주로 사용함 |
new 키워드를 이용 생성자 호출; new foo() | 새롭게 생성된 인스턴스 객체 | 객체 지향 프로그래밍에서 주로 사용함 |
.call 또는 .apply 호출; foo.call() foo.apply() |
첫번째 인자로 전달된 객체 | this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 엘리먼트를 풀어서 인자로 넘기고자 할 때 유용함 |
Global; console.log(this) | window (strict mode에서는 undefined) | module.exports(전역에서 this 참조) |
Function; 호출 foo() | window (strict mode에서는 undefined) | global |
- 브라우저 환경에서 this는 기본적으로 window 객체
- node.js 환경에서 this는 기본적으로 module.exports 객체
- node.js 환경에서는 global이라는 객체가 존재
Method 호출
: 객체의 속성 값으로 담긴 함수
화살표 함수로 작성된 메소드 호출시 this = module.exports
메소드 선언시 화살표 함수 사용X or 화살표 함수 사용시 this 사용X
생성자 호출
: 객체를 new 키워드를 이용해 만듦.
객체 = 인스턴트. 인스턴트.메소드() 형태의 호출.
new가 안 붙은 경우, this는 전역 객체를 가리킨다.
함수에도 메소드가 있다 => call(), apply(), bind()
3. Difference between “==” and “===” ?
==과 ===은 조건식에서 사용한다.
어떤 것이 같은지 판별할 때 사용하는 것이다.
==은 값만 비교하지만 ===은 값과 타입을 같이 비교한다.
undefined와 null을 비교할 때 ==을 사용하면 true가 출력된다.
왜냐면 둘 다 빈값이기 때문이다.
그러나 ===을 사용하면 값 뿐만 아니라 type까지 비교하게 되는데
undefined는 undefined타입이나 null은 object타입이므로 둘은 같지 않다고 판별되어 false가 출력된다.
4. ES6에 대해서 알고 계신가요? 사용하고 있는 ES6 feature들을 설명해 주세요
자바스크립트 언어의 표준.
- Destructing 구조분해할당
- Spread Operating Spread 연산자
- Rest Parameters
- Default Parameters
- Template Literals 템플릿/백틱
- Arrow Fuctions 화살표함수
- for...of loop
자세한 설명: nomadkim880901.tistory.com/330
velog.io/@surim014/2020-01-02-1901-%EC%9E%91%EC%84%B1%EB%90%A8
5. let 과 var 의 차이점과 활용도를 알려주세요.
var, let, const 의 차이점
1) var (변수 재선언 가능)
var variable = '최초변수선언';
console.log(variable); //최초변수선언
var variable = '변수재선언';
console.log(variable); //변수재선언
같은 이름의 변수가 남용될 수 있는 단점이 존재하여 이를 보완하기 위해 let, const 가 추가됨.
2) let(변수 재선언 불가능, 변수 재할당 가능)
let variable = '최초변수선언';
console.log(variable) //최초변수선언
variable = '변수재할당';
console.log(variable) //변수재할당
let variable = '변수재선언';
console.log(variable) //변수재선언 -> 오류가 발생한다.
오류값: Uncaught SyntaxError: Identifier 'variable' has already been declared
3) const(변수 재선언 불가능, 변수 재할당 불가능)
const variable = '변수선언'
console.log (variable); //변수선언
variable = '변수 재할당'
console.log (variable); //변수재할당 -> 불가능
const variable = '변수 재선언'
console.log (variable); //변수 재선언 -> 불가능
6. javascript 와 node 는 어떻게 다른가요?
- NodeJS: NodeJS는 서버 측에서 자바 스크립트를 실행할 수있는 크로스 플랫폼 및 오픈 소스 자바 스크립트 런타임 환경입니다. Nodejs를 사용하면 자바 스크립트 코드가 브라우저 외부에서 실행될 수 있습니다. Nodejs는 많은 모듈과 함께 제공되며 주로 웹 개발에 사용됩니다.
- Javascript: Javascript는 스크립팅 언어입니다. 주로 JS로 축약됩니다. Javascript는 ECMA 스크립트의 업데이트 된 버전이라고 할 수 있습니다. Javascript는 Oops 개념을 사용하는 고급 프로그래밍 언어이지만 프로토 타입 상속을 기반으로합니다.
참고: www.geeksforgeeks.org/difference-between-node-js-and-javascript/
7. hoisting 에 대해 설명해주세요.
함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말합니다.
호이스팅 특징
- 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
- 자바스크립트 ***Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
- 함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
- 유효 범위: 함수 블록 {} 안에서 유효
- 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
- 실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
- 실제 메모리에서는 변화가 없다.
*** parsing은 입력 문장에서 단어들의 기능이 문법규칙에 맞는가를 분석하는 것이다.
자세한 설명: nomadkim880901.tistory.com/299
8. call apply bind 에 대해 설명해 보세요. 언제 다르게 쓰나요?
call 메소드
.call 호출은 명시적으로 this를 지정할 때 사용. 첫번째 인자가 항상 this.
foo.call(context). context를 this로 지정하고, foo() 함수를 실행.
call의 두번째 인자 이후로는 파라미터로 전달됨.
function printProfile(name, age, ...args) {
return `${this.type} ${name} 나이:${age}${args.length === 0 ? "" : " " + this.feature + ":" + args.join(",")}`;
}
const artist = { type: "아티스트", feature: "노래" };
printProfile.call(artist, "BTS", 7, "ON", "Dynamite")
//아티스트 BTS 나이:7 노래:ON,Dynamite
apply 메소드
.apply 호출은 명시적으로 this를 지정할 때 사용. 첫번째 인자가 항상 this.
apply의 두번째 인자는 배열.
function printProfile(name, age, ...args) {
return `${this.type} ${name} 나이:${age}${args.length === 0 ? "" : " " + this.feature + ":" + args.join(",")}`;
}
const artist = { type: "아티스트", feature: "노래" };
printProfile.apply(artist, ["BTS", 7, "ON", "Dynamite"])
//아티스트 BTS 나이:7 노래:ON,Dynamite
prototype 기능 빌려쓰기
const array1 = ["code", "states"];
const array2 = ["immersive", "course"];
const arrayNumbers = [5, 10, 4, 9];
Array.prototype.concat.call(array1, array2, arrayNumbers)
//["code","states","immersive","course", 5, 10, 4 ,9]
Array.prototype.concat.apply(array1, [array2])
//["code","states","immersive","course"]
유사 배열 다루기 가능
const nodeList = {
length: 3,
0: "div#target",
1: "li",
2: "span#new"
};
Array.prototype.slice.apply(nodeList, [0, 1]) // ["div#target"]
Array.prototype.map.call(nodeList, node => node.split("#")[0]) //["div","li","span"]
일반 배열 예시
bind 메소드
bind는 함수를 실행하지 않고, this 컨텍스트를 담은 함수를 리턴.
bind의 인자 순서는 call과 동일.
CASE1
: 각 버튼을 클릭했을때 클릭된 버튼의 이름이 출력되게 하려면?
Solution1
user를 this로 바인딩 시키는 방법
solution2
this를 사용하지 않고, 인자를 전달하는 방법
solution3
bind를 사용하지 않고 인자를 전달하는 방법
9. 실행하면 결과가 어떻게 나오나요? 왜 그런가요?
(function() {
console.log(1);
setTimeout(function(){console.log(2)}, 1000);
setTimeout(function(){console.log(3)}, 0);
console.log(4);
})();
1, 4, 3, 2 순서대로 출력됩니다. 이 모든 과정이 자바스크립트의 이벤트 루프입니다.
- 메인 함수 호출 -> 프레임으로 stack에 push → 브라우저 첫번째 statement(console.log(1))를 stack에 넣음 → 해당 프레임은 stack에서 pop된다.→ 1 콘솔에 표기.
- 두번째 statement(콜백 function(console.log(2)) setTimeout() ) 가 콜스택으로 push → setTimeout() 함수는 제공된 콜백을 딜레이하기 위해 브라우저 API를 사용 → 타이머를 돌리기위해 콜백이 브라우저로 넘어가면 setTimeout()을 가진 프레임은 pop
- 세번째 statement(콜백 function(console.log(3)) setTimeout() ) 가 콜스택으로 push → setTimeout() 함수는 제공된 콜백을 딜레이하기 위해 브라우저 API를 사용 → 타이머를 돌리기위해 콜백이 브라우저로 넘어가면 setTimeout()을 가진 프레임은 pop
- 브라우저에 콜백 함수 실행을 위한 타이머가 돌아가는 도중 console.log(4)가 콜스택에 push (제공된 딜레이는 0ms 였기 때문에, 콜백은 브라우저가 콜백을 받자마자 메시지 큐에 바로 추가)
- 마지막 statement의 실행 후 main() 프레임은 콜스텍 밖으로 pop → 콜스택은 빈(empty)가 된다. 브라우저가 어떤 메시지를 큐에서 콜스택으로 push하기 위해서는 먼저 콜스택을 반드시 비워야 한다. setTimeout()의 딜레이가 0초임에도 불구 하고, 콜백이 콜스택에 존재했던 모든 프레임이 실행될 때까지 기다려야 했던 이유이다
- 콜백 console.log(3), console.log(2)가 콜스택에 push된 후 실행 → 3, 2 가 차례대로 콘솔에 나타남.
자세한 설명: velog.io/@thms200/Event-Loop-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84
10. javascript array가 c 언어의 array와 어떻게 다른지 설명해 주세요
자료형
자바스크립트는 변수를 선언할 때 별도로 자료형을 명시하지는 않는다.
C언어가 자료형에 따라 int, char 등을 사용해 변수를 선언하는 반면, 자바스크립트는 var 라는 키워드를 사용하여 변수나 객체를 선언한다. var에다가 문자를 넣으면 문자형이되고, 정수를 넣으면 정수형이 된다.
이런 특징 때문에 자바스크립트를 느슨한 타입(loosely typed) 언어, 혹은 동적(dynamic) 언어 라고 부른다.
입력되는 값을 인터프리터가 알아서 파악한다는 의미인데, 이것이 가능한 이유는 내장형 객체라는 개념으로 기본 자료형(Primitive)이 이미 자바스크립트 내에 존재하기 때문이다. 기본형 외에 배열같은 객체 자료형(Objects)이 있다.
a) 기본 자료형 (Primitive values)
- C언어와는 다르게, 기본 자료형의 모든 값은 한번 선언되면 수정이 불가능한 불변값(immutable value)이다.
1) Number
10진수, 8진수, 16진수와 소수점이 있는 실수 및 지수를 사용할 수 있다.
var number = 1; var float = 5.6;
그밖에도 Number 타입에는 3가지 상징적인 값이 정의되어 있다. +Infinity, -Infinity, 그리고 NaN(숫자가 아님)이 있다.
2) String
문자열을 작성할 때는 큰따옴표나 작은따옴표 모두 사용 가능하다. C언어와 마찬가지로 문자열의 첫 글자는 0번 인덱스로, 그 다음 글자는 1번 인덱스로 참조할 수 있다. 하지만 그 값을 수정할 수는 없다.
원래 문자열에서 일부가 수정된 다른 문자열을 만드는건 가능하다.
- 원래 문자열에서 각각의 글자를 추출하거나 String.substr()을 사용해서 만든 부분 문자열
- 접합 연산자 (+) 나 String.concat() 으로 두 문자열을 합친 문자열
3) Boolean
Boolean 은 논리적인 요소를 나타내고, true 와 false 의 두 가지 값을 가질 수 있다. true와 false는 예약어로서 따옴표를 쓰지 않으니 주의.
4) Null
NULL 타입은 딱 한가지 값 null 을 가진다. 어떤 값이 의도적으로 비어있음을 표현하며 boolean 연산에서는 거짓으로 취급한다.
5) Undefined
값을 할당하지 않은 변수는 undefined 값을 가진다.
이 외에도 ECMAScript 6에서 추가된 Symbol 타입이 있다.
b) 객체 자료형 (Objects)
- 자바스크립트(뿐만 아니라 거의 모든 컴퓨터 개념)에서 객체는 식별자로 참조할 수 있는, 메모리에 저장된 값이다.
- 자바스크립트 객체는 키와 값의 매핑이다. 키는 문자열이고 값은 다른 어떤 값도 될 수 있다.
- new 함수
- 객체 자료형과 기본형 자료형의 가장 큰 차이점은 Reference(참조)에 있다. 기본형 변수는 다른 변수에 값을 할당하거나 함수 인자로 넘길 때 값을 복사하여 전달하지만, 객체는 메모리 주소를 복사시키며 값 자체는 복사되지 않아 같은 객체를 참조하게 된다.
- 즉, 함수를 호출할 때 new을 붙이면 새로운 객체를 만든 후에 이를 리턴한다.
1) Array
자바스크립트의 배열은 []나 new Array()로 생성하며, 크기의 제약이 없고, 하나의 배열에 서로 다른 타입의 변수가 들어갈 수 있다.
var array1 = [1, 2, 3]; var array2 = new Array(2,4,5,"a",'b');
- 배열 연산을 위한 다양한 메소드를 지원한다.var array = new Array(2,4,5,"a",'b'); array.length() //길이 array.push(값) //맨 뒤에 요소 추가 array.pop() //맨 뒤 요소 삭제 array.unshift(값) //맨 앞에 요소 추가 array.shift() //맨 앞 요소 삭제 array.sort() //요소 정렬
2) Dictionary
- key:value 형태로 저장한다.
- 중괄호 {} 혹은 new Object() 생성자를 사용해 생성한다.
- 콤마 , 를 이용해 여러 개의 키-값 쌍을 저장할 수 있다.
var me = {'name':'daelee', 'age':24}; console.log(me.age); > 24 3) Date
- 시간을 나타낼 때 사용하는 객체 자료형
- new Date() 생성자를 사용해 생성
- 현재 날짜와 시간을 가지는 인스턴스 반환 (현재의 기준은 시스템 시계 설정 따름)
- 자세한 사용법은 이 블로그 참고.
javascript 와 c 의 차이점:
velog.io/@hidaehyunlee/JavaScript-C-%EB%AC%B8%EB%B2%95-%EB%B9%84%EA%B5%90
m.post.naver.com/viewer/postView.nhn?volumeNo=17988573&memberNo=21815
“Array()” and “[]” difference: www.geeksforgeeks.org/whats-the-difference-between-array-and-while-declaring-a-javascript-array/
11. deep 과 shallow object copy에 대해 설명해 주시고 용도가 있다면 말씀해 주세요
자바스크립트에서 자료형은 아래와 같이 크게 기본형(Primitive Value) 과 참조형(Reference Type) 2가지로 나눌수 있습니다.
기본형 (Primitive Value)
- Boolean
- Null
- Undefined
- Number
- String
참조형(Reference Type)
- Object(배열, 일반 객체, 함수)
일반 문자열, 숫자, 불린, Null, Undefined 같은 기본 자료형의 경우(Primitive Value)는
var string = 'hello';
var copy = string;
console.log(copy); // 'hello'
하면 바로 복사가 되는데요. 참조형(배열, 일반 객체, 함수)도 마찬가지이긴 합니다만, 복사된 값을 조작할 때 차이가 있습니다. 다시 위의 예를 보면
var string = 'hello';
var copy = string; console.log(copy); // 'hello' copy = 'hi';
console.log(string); // 'hello'
이번엔 copy 값을 hi로 바꿔봤습니다. 기존 string 값은 변화가 없겠죠? copy에 값만 복사해 줬을 뿐 더이상 연관이 없으니까요. 객체의 경우를 볼까요?
var array = ['a', 'b', 'c'];
var ref = array;
ref[0] = 'd';
console.log(array); // ['d', 'b', 'c']
ref변수에 array 배열을 대입했는데요. ref의 첫 번째 항목을 변경했더니 array의 첫 번째 항목도 같이 변경되었습니다. 이상하죠? 이게 객체의 특징입니다. 참조 타입일 경우 참조 값만 복사하기 때문에 같은 객체를 바라봅니다.
이렇게 참조타입인 객체는 다른 변수에 대입할 때 값을 복사하는 게 아니라 참조(메모리의 주소)를 복사합니다.
copy에는 두 가지가 있습니다. shallow copy(얕은 복사)와 deep copy(깊은 복사)인데요. shallow copy는 가장 상위 객체만 새로 생성되고 내부 객체들은 참조 관계인 경우를 의미합니다. deep copy는 내부 객체까지 모두 새로 생성된 것을 의미합니다.
1) 얕은 복사
var employeeDetailsOriginal = { name: 'JayKim', age: 30, profession: 'software Enginner' };
var employeeDetailsDuplicate = employDetailsOriginal;
//Shallow Copy
employDetailsDuplicate.name = 'NameChanged'
//This statement will also change name from employeeDetailsOriginal,
//since we have a shallow copy, or a reference to var employeeDetailsOriginal.
//This means, you’re losing the original data as well.
2) 깊은 복사
var employDetailsDuplicate = {
name: employDetailsOriginal.name,
age: employDetailsOriginal.age,
Profession: employDetailsOriginal.Profession
};
//Deep copy
Now if you change employeeDetailsDuplicate.name,
it will only affect employeeDetailsDuplicate and not employeeDetailsOriginal.
So How to copy JavaScript object to new variable NOT by reference?
참고
제로초 객체의 복사: www.zerocho.com/category/JavaScript/post/5750d384b73ae5152792188d
medium.com/@manjuladube/understanding-deep-and-shallow-copy-in-javascript-13438bad941c
깊은복사와 얕은 복사에 대한 심도있는 이야기: medium.com/watcha/%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC%EC%99%80-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%AC%EB%8F%84%EC%9E%88%EB%8A%94-%EC%9D%B4%EC%95%BC%EA%B8%B0-2f7d797e008a
12. javascript 의 undeclared, undefined, null 의 차이점은 무엇인가요
1) undeclared (선언되지 않은) 상태
먼저 undeclared의 경우 "use strict" 명령어를 통해 엄격모드 로 진입하지 않으면, 만나기 힘듭니다.
아래와 같이 엄격모드가 아닌 자바스크립트에서 선언되지 않은 변수에 값을 할당하면 자동으로 global 변수로 취급되기 때문입니다.
"use strict"로 엄격모드에 진입하면 선언되지 않은 변수에 값을 할당하려고 할 때 다음과 같은 에러가 등장합니다.
2) undefined (정의되지 않은) 상태
정의되지 않은 상태는 변수를 선언한 뒤에 아무것도 할당하지 않은 상태를 말합니다. 만일 아무런 값도 반환하지 않는 함수를 특정 변수에 할당하면, 변수는 undefined 상태를 갖게 됩니다. 이러한 상태를 체크하기 위해 엄격한 동등 비교 (===) 연산자나 typeof 키워드를 사용하여 'undefined' 문자열을 받아낼 수 있습니다. 엄격하지 않은 동등 비교 (==)는 null 값과 undefined를 비교했을 때도 true를 반환하므로 부정확합니다.
var foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true
console.log(foo == null); // true 이래서 == 연산자를 조심해야 합니다.
function bar() {}
var baz = bar();
console.log(baz); // undefined
3) null
null 변수는 명시적으로 null이 할당된 경우 생깁니다. null은 아무런 값도 나타내지 않습니다만 무언가 할당은 된 것이기 때문에 undefined와 다릅니다. null을 체크하기 위해서는 간단하게 === 연산자를 사용하면 됩니다. null에 typeof를 하면 undefined에서는 'undefined'가 나왔던 것과 다르게 'object'가 나오게 되니 유의해야 합니다.
var foo = null;
console.log(foo === null); // true
console.log(typeof foo === 'object'); // true
console.log(foo == undefined); // true `==`는 trusy falsy만 비교하게 됩니다.
실제로 코딩할 때는 변수를 할당되지 않거나 정의되지 않은 채로 내버려 두는 경우는 거의 없습니다. 또 실제는 IDE에 내장된 플러그인이나 lint가 민감하게 반응해줍니다.
13. 모든 자바스크립트 파일을 브라우저에서 한번에 loading 할 때 문제점
14. 자바스크립트 Prototype에 관해 설명해주세요 (상속)
자바스크립트의 객체는 명세서에서 명명한 [[Prototype]]이라는 숨김 프로퍼티를 갖습니다. 이 숨김 프로퍼티 값은 null이거나 다른 객체에 대한 참조가되는데, 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부릅니다.
프로토타입의 동작 방식은 '신비스러운’면이 있습니다. object에서 프로퍼티를 읽으려고 하는데 해당 프로퍼티가 없으면 자바스크립트는 자동으로 프로토타입에서 프로퍼티를 찾기 때문이죠. 프로그래밍에선 이런 동작 방식을 '프로토타입 상속’이라 부릅니다. 언어 차원에서 지원하는 편리한 기능이나 개발 테크닉 중 프로토타입 상속에 기반해 만들어진 것들이 많습니다.
[[Prototype]] 프로퍼티는 내부 프로퍼티이면서 숨김 프로퍼티이지만 다양한 방법을 사용해 개발자가 값을 설정할 수 있습니다.
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal;
__proto__는 [[Prototype]]용 getter·setter입니다.
__proto__는 브라우저 환경에서만 지원하도록 자바스크립트 명세서에서 규정하였는데, 실상은 서버 사이드를 포함한 모든 호스트 환경에서 __proto__를 지원합니다.
사실, 객체 rabbit에서 프로퍼티를 얻고싶은데 해당 프로퍼티가 없다면, 자바스크립트는 자동으로 animal이라는 객체에서 프로퍼티를 얻습니다. 이제 “rabbit의 프로토타입은 animal입니다.” 혹은 "rabbit은 animal을 상속받는다."라고 말 할 수 있게 되었습니다.
프로토타입을 설정해 준 덕분에 rabbit에서도 animal에 구현된 유용한 프로퍼티와 메서드를 사용할 수 있게 되었네요. 이렇게 프로토타입에서 상속받은 프로퍼티를 '상속 프로퍼티(inherited property)'라고 합니다.
참고: ko.javascript.info/prototype-inheritance
15. promise에 대해서 설명해 주세요
let promise = new Promise(function(resolve, reject) {
// 프라미스가 만들어지면 executor 함수는 자동으로 실행됩니다.
// 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result가 'done'이 됩니다.
setTimeout(() => resolve("done"), 1000);
});
- new Promise에 전달되는 함수는 executor(실행자, 실행 함수) 라고 부릅니다.
- executor는 new Promise가 만들어질 때 자동으로 실행되는데,
- 결과를 최종적으로 만들어내는 제작 코드를 포함합니다.
- executor의 인수 resolve와 reject는 자바스크립트가 자체적으로 제공하는 콜백입니다.
- executor에선 상황에 따라 인수로 넘겨준 콜백 중 하나를 반드시 호출해야 합니다.
1. resolve(value) — 일이 성공적으로 끝난 경우, 그 결과를 나타내는 value와 함께 호출
2. reject(error) — 에러 발생 시 에러 객체를 나타내는 error와 함께 호출
- new Promise 생성자가 반환하는 promise 객체는 다음과 같은 내부 프로퍼티를 갖습니다.
1. state — 처음엔 "pending"(보류)이었다 resolve가 호출되면 "fulfilled", reject가 호출되면 "rejected"로 변합니다.
2. result — 처음엔 undefined이었다, resolve(value)가 호출되면 value로, reject(error)가 호출되면 error로 변합니다.
Consuming Code Part
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve("done!"), 1000);
setTimeout(() => reject(new Error("에러 발생!")), 1000);
});
promise
.then(
result => alert(result), // 1초 후 "done!"을 출력
)
.catch(err => alert(err))
.finally(() ==> alert("무슨 일이 일어나든 실행됩니다!!")
.then : promise 가 이행되었을때 실행되는 함수이고 실행 결과(인자)를 받습니다.
.catch : promise 의 결과가 실패일 경우 new Error("에러 발생") 인자를 받아 alert 합니다.
.finally: 결과가 어떻든 마무리가 필요할 때 유용합니다. 단 finally 엔 인수가 없습니다.
특징
- 콜백(resolve, reject)은 자바스크립트 Event Loop이 현재 실행중인 콜 스택을 완료하기 이전에는 절대 호출되지 않습니다.
- 비동기 작업이 성공하거나 실패한 뒤에 then() 을 이용하여 추가한 콜백의 경우에도 위와 같습니다.
- then()을 여러번 사용하여 여러개의 콜백을 추가 할 수 있습니다. 그리고 각각의 콜백은 주어진 순서대로 하나 하나 실행되게 됩니다.
nomadkim880901.tistory.com/349
16. Array prototype splice 와 slice의 차이점은 무엇인가요
[1] Array.prototype.slice()
slice() 메소드는 begin부터 end 전까지의 복사본을 새로운 배열 객체로 반환한다. 즉, 원본 배열은 수정되지 않는다.
slice(start[, end])
start: 추출 시작점에 대한 인덱스.
- undefined인 경우: 0부터 slice
- 음수를 지정한 경우: 배열의 끝에서부터의 길이를 나타낸다. slice(-2)를 하면 배열의 마지막 2개의 요소를 추출한다.
- 배열의 길이와 같거나 큰 수를 지정한 경우: 빈 배열을 반환한다.
end: 추출을 종료할 기준 인덱스. (end를 제외하고 그 전까지의 요소만 추출한다.)
- 지정하지 않을 경우: 배열의 끝까지 slice
- 음수를 지정한 경우: 배열의 끝에서부터의 길이를 나타낸다. slice(2, -1)를 하면 세번째부터 끝에서 두번째 요소까지 추출
- 배열의 길이와 같거나 큰 수를 지정한 경우: 배열의 끝까지 추출.
반환값: 추출한 요소를 포함한 새로운 배열.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr1 = arr.slice(3, 5); // [4, 5]
var arr2 = arr.slice(undefined, 5); // [1, 2, 3, 4, 5]
var arr3 = arr.slice(-3); // [8, 9, 10]
var arr4 = arr.slice(-3, 9); // [8, 9]
var arr5 = arr.slice(10); // []
var arr6 = arr.slice(4); // [5, 6, 7, 8, 9, 10]
var arr7 = arr.slice(undefined); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var arr8 = arr.slice(5, -4); // [6]
var arr9 = arr.slice(2, 15); // [3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr1); // [4, 5]
console.log(arr2); // [1, 2, 3, 4, 5]
console.log(arr3); // [8, 9, 10]
console.log(arr4); // [8, 9]
console.log(arr5); // []
console.log(arr6); // [5, 6, 7, 8, 9, 10]
console.log(arr7); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr8); // [6]
console.log(arr9); // [3, 4, 5, 6, 7, 8, 9, 10]
출처: https://im-developer.tistory.com/103 [Code Playground]
[2] Array.prototype.splice()
splice() 메소드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경한다. 이 메소드는 원본 배열 자체를 수정한다.
splice(start[, deleteCount[, item1[, item2[, ...]]]])
start: 배열의 변경을 시작할 인덱스.
- 음수를 지정한 경우: 배열의 끝에서부터 요소를 센다.
- 배열의 길이보다 큰 수를 지정한 경우: 실제 시작 인덱스는 배열의 길이로 설정
- 절대값이 배열의 길이보다 큰 경우: 0으로 세팅
deleteCount: 배열에서 제거할 요소의 수.
- 생략 / 값이 array.length - start보다 큰 경우: start부터의 모든 요소를 제거.
- 0 이하의 수를 지정: 어떤 요소도 제거되지 않는다.
item1, item2, ... : 배열에 추가할 요소.
- 지정하지 않는 경우: splice()는 요소 제거만 수행한다.
반환값: 제거한 요소를 담은 배열.
- 아무 값도 제거하지 않았으면 빈 배열을 반환한다.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var arr1 = arr.splice(10, 2, 'a', 'b', 'c');
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "a", "b", "c"]
console.log(arr1); // [11, 12]
출처: https://im-developer.tistory.com/103 [Code Playground]
참고: im-developer.tistory.com/103
17. OOP의 4가지 특징과 javascript를 활용하여 OOP스럽게 개발해 본 경험이 있다면 이야기해 주세요
- Abstraction(추상화)
추상은 어떠한 존재가 가지고 있는 여러가지의 속성 중에서 특정한 속성을 가려내어 포착하는 것을 의미한다.
즉, 그 존재가 가지고 있는 가장 특징적인 속성들을 파악해나가, 내부 구현을 알지 못해도 노출되어 있는 메소드( = 인터페이스.)로 공통적인 특성을 발견할 수 있는 것을 말한다.
상위 개념 아이폰: 애플에서 만든 iOS 기반의 스마트폰
아이폰 클래스 기반의 하위 개념 아이폰X: 애플에서 만든 iOS 기반의 스마트폰이며, 홈 버튼이 없고 베젤리스 디자인이 적용된 아이폰
아이폰7: 애플에서 만든 iOS 기반의 스마트폰이며, 햅틱 엔진이 내장된 홈 버튼을 가지고 있는 아이폰.
아이폰 SE: 애플에서 만든 iOS 기반의 스마트폰이며, 사이즈가 작아서 한 손에 잡을 수 있는 아이폰.
- Inheritance(상속)
부모(Basic class) 의 속성을 물려받는 것을 말한다.
class IPhone {
String manufacturer = "apple";
String os = "iOS";
}
class IPhone7 extends IPhone {
int version = 7;
}
class Main {
public static void main (String[] args) {
IPhone7 myIPhone7 = new IPhone7();
System.out.println(myIPhone7.manufacturer); //apple
System.out.println(myIPhone7.os); //iOS
System.out.println(myIPhone7.version); //7
}
}
추상화가 잘된 클래스를 하나만 만들어놓는다면 그와 비슷한 속성이 필요한 다른 클래스를 생성할 때 그대로 재사용할 수 있다는 말이다. 그리고 만약 아이폰 시리즈 전체에 걸친 변경사항이 생겼을 때도 IPhone7, IPhoneX와 같은 클래스는 건드릴 필요없이 IPhone 클래스 하나만 고치면 이 클래스를 상속받은 모든 하위 클래스에도 자동으로 적용되므로 개발 기간도 단축시킬 수 있고 휴먼 에러가 발생할 확률도 줄일 수 있다.
- Encapsulation(캡슐화 || 은닉화)
어떠한 클래스를 사용할 때 내부 동작이 어떻게 돌아가는지 모르더라도 사용법만 알면 쓸 수 있도록 클래스 내부를 감추는 기법이다. 클래스를 캡슐화 함으로써 클래스를 사용하는 쪽에서는 머리 아프게 해당 클래스의 내부 로직을 파악할 필요가 없어진다. 또한 클래스 내에서 사용되는 변수나 메소드를 원하는 대로 감출 수 있기 때문에 필요 이상의 변수나 메소드가 클래스 외부로 노출되는 것을 방어햐여 보안도 챙길 수 있다.
여러 속성을 class 내에 모아두어 Reduce complexity + increase reusuability 를 실현할 수 있다.
이렇게 클래스 내부의 데이터를 감추는 것을 정보 은닉(Information Hiding)이라고 하며, 보통 public, private, protected 같은 접근제한자를 사용하여 원하는 정보를 감추거나 노출시킬 수 있다.
// Capsulation.java
class Person {
public String name;
private int age;
protected String address;
public Person (String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
}
class CapsulationTest {
public static void main (String[] args) {
Person evan = new Person("Evan", 29, "Seoul");
System.out.println(evan.name);
System.out.println(evan.age);
System.out.println(evan.address);
}
}
에러가 난 부분은 private 접근제한자를 사용한 멤버변수인 age이다. 이처럼 private 접근제한자를 사용하여 선언된 멤버 변수나 메소드는 클래스 내부에서만 사용될 수 있고 외부로는 아예 노출 자체가 되지 않는다.
- Polymorphism(다형성)
특정한 기능을 선언(설계)부분과 구현(동작)부분으로 분리한 후 구현부분을 다양한 방법으로 만들어 선택 사용할 수 있게 하는 개념입니다.
예제의 Hero 클래스는 name 멤버 변수를 생성자로부터 받아서 자신의 멤버 변수로 추가하는 기능을 가지고 있기 때문에 추상 클래스를 사용하는 것이 더 적절하다. 그럼 이제 추상 클래스를 사용하여 ultimate 메소드의 구현을 강제해보도록 하자.
abstract class Hero {
public String name;
Hero (String name) {
this.name = name;
}
// 내부 구현체가 없는 추상 메소드를 선언한다.
public abstract void ultimate ();
}
class Reinhardt extends Hero {
Reinhardt () {
super("reinhardt");
}
public void ultimate () {
System.out.println("망치 나가신다!");
}
}
class McCree extends Hero {
McCree () {
super("mccree");
}
public void ultimate () {
System.out.println("석양이 진다. 빵야빵야");
}
}
class Mei extends Hero {
Mei () {
super("mei");
}
public void ultimate () {
System.out.println("꼼짝 마! 움직이지 마세요!");
}
}
이렇게 추상 클래스인 Hero를 상속받은 영웅 클래스들은 무조건 ultimate 메소드를 구현해야한다. 이렇게 메소드명이 통일되면 영웅 클래스를 가져다 쓰는 입장에서는 궁극기를 발동시키고 싶을 때 어떤 메소드를 호출해야할지 이제 더 이상 고민할 필요가 없다.
class Main {
public static void main (String[] args) {
Mei myMei = new Mei();
Reinhardt myReinhardt = new Reinhardt();
McCree myMcCree = new McCree();
Main.doUltimate(myMei);
Main.doUltimate(myReinhardt);
Main.doUltimate(myMcCree);
}
public static void doUltimate (Hero hero) {
// Hero 클래스를 상속받은 클래스는
// 무조건 ultimate 메소드를 가지고 있다는 것이 보장된다.
hero.ultimate();
}
}
코드가 훨씬 심플해지지 않았는가? 추상 메소드를 사용하여 클래스 내부의 ultimate라는 메소드의 구현을 강제했기 때문에 Hero 클래스를 상속받은 영웅 클래스에 해당 메소드가 없을 확률은 전혀 없다. 그렇기 때문에 사용하는 입장에서는 깊은 고민없이 안심하고 ultimate 메소드를 호출할 수 있다.
또한 ultimate 메소드는 모든 영웅 클래스들이 가지고 있는 메소드이지만 내부 구현은 전부 다르기 때문에 발동하는 스킬 또한 영웅 별로 다르게 나올 것이다. 이런 것을 바로 다형성이라고 하는 것이다.
요약
- 추상화 - 각 객체들의 공통된 특성을 뽑아낸다.
- 캡슐화 - 데이터를 은닉하고 데이터의 기능을 노출시키지 않는 의미로 사용됨.
- 상속성 - 객체지향의 정수로 상속성이 없다면 객체지향의 의미가 없어질 정도로 중요한 요소이다. 하나의 클래스가 가진 특징(데이터, 함수)을 그대로 다른클래스에 물려줄때 사용된다.
- 다형성 - 같은 함수를 받아도 각자 다른 일을 하는 것을 의미한다
OOP 스럽게 개발해 본 경험? 스프린트 공부했던 경험. class형/ 함수형
참고: evan-moon.github.io/2019/08/24/what-is-object-oriented-programming/
18. 탱크 게임 (혹은 기타 게임) 을 OOP적으로 어떻게 개발할 수 있을지 설명해 보세요
1) 먼저 추상화를 통해 탱크의 공통적인 특성이 무엇인지 파악합니다. 즉, 포, 움직임, 속도 등 입니다.
2) 상속을 이용하여 각 자식 탱크에 부모의 속성(탱크의 공통적인 특성)을 물려 줍니다.
3) 유저의 사용성을 높일 수 있도록 유저가 알 필요가 없는 정보들은 은닉화를 통해 감추고 겉으로 드러난 메소드 또는 옵션을 이용하게 만듭니다.
4) 다형성을 이용하여 각 탱크에 독립적인 기능 또는 특성을 부여합니다.
19. 익명함수와 선언적함수의 차이가 무엇인가요
1) 익명함수
익명함수를 선언하고 사용하기 위해서는 변수에 넣어서 사용하여야 한다.
<script>
function () {
//실행코드 작성
};
</script>
<script>
var func = function () {
alert('This is anonymous function');
};
func();
</script>
2) 선언적함수
함수를 선언할 때 이름을 붙여주는 함수를 말한다. 즉, 따로 변수에 넣어주지 않고 선언할 때 붙여준 이름으로 호출하면 된다.
<script>
function 함수이름 () {
}
함수이름();
</script>
익명함수와 선언적함수의 차이점
웹브라우저가 script 태그 내부의 내용을 위에서부터 한줄씩 읽기 전에 선언적 함수부터 먼저 읽는다는 것이다.
익명함수 Case
웹브라우저는 코드를 읽을 때 위에서 부터 한줄씩 차례로 읽는데,
익명함수를 저장한 변수를 선언하기 이전에 그 변수를 사용했기 때문에 오류가 발생한다.
<script>
func();
var func = function () {alert('function A')};
var func = function () {alert('function B')};
</script>
선언적함수 Case
웹브라우저가 코드를 읽을 때는 위에서 부터 차례로 읽기는 하나,
그 전에 선언적 함수가 있으면 그 코드부터 먼저 읽은 뒤에 차례로 읽어 나가기 때문에 오류가 발생하지 않는다.
<script>
func();
function func() {alert('function A')};
function func() {alert('function B')};
</script>
참고: first-class.tistory.com/15
20. Can you describe the main difference between a "forEach loop" and a "map loop" and why you would pick one versus the other?
1) forEach
forEach()는 각 배열 요소에 대해 한 번씩 callback 함수를 실행합니다. map()과 reduce()와는 달리 undefined를 반환하기 때문에 메서드 체인의 중간에 사용할 수 없습니다. forEach()는 배열을 변형하지 않습니다.
const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// expected output: "a"
// expected output: "b"
// expected output: "c"
2) map
새로운 배열 요소를 생성하는 함수. 배열의 각 요소에 대해 실행한 callback의 결과를 모은 새로운 배열.
const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
즉, forEach()가 배열 요소마다 한 번씩 주어진 함수(콜백)를 실행하는 것과 달리, map()은 배열 내의 모든 요소 각각에 대하여 주어진 함수(콜백)를 호출한 결과를 모아 새로운 배열을 반환한다는 특징을 가지고 있습니다.
재사용이 요구되는 로직일 경우에는, forEach 를 이용하여 새로운 배열을 만들어 사용하고,
아닐 경우에는, map 을 이용하여 기존 배열의 변형된 배열을 바로 리턴받아 사용한다.
21. 타입스크립트에 대해서 들어보셨나요? 사용해본 경험은? 어떻게 다른가요? 장점은?
코드스테이츠에서의 파이널 프로젝트에서 리액트와 함께 사용했던 경험이 있습니다.
부모에서 자식 컴포넌트로 인자 또는 메소드를 전달해 줄때 아래와 같이 인자의 타입을 interface 를 통해 선언해 주는 방식으로 구현했습니다.
interface Props {
modalIsOpen: boolean;
setIsOpen: (e: boolean) => void;
message: string;
}
export default function NotificationModal(props: Props): ReactElement {
const { modalIsOpen, setIsOpen, message } = props;
후략
장점
1) 정적 타입
function sum(a, b) {
return a + b;
}
sum('x', 'y'); // 'xy'
위 함수를 정의한 개발자의 의도는 아마도 2개의 숫자 타입 인수를 전달받아 그 합계를 반환하려는 것으로 추측된다. 하지만 코드상으로는 어떤 타입의 인수를 전달하여야 하는지, 어떤 타입의 반환값을 리턴해야 하는지 명확하지 않다.
위 코드는 자바스크립트 문법상 어떠한 문제도 없으므로 자바스크립트 엔진은 아무런 이의 제기없이 위 코드를 실행할 것이다. 이러한 상황이 발생한 이유는 변수나 반환값의 타입을 사전에 지정하지 않는 자바스크립트의 동적 타이핑(Dynamic Typing)에 의한 것이다.
function sum(a: number, b: number) {
return a + b;
}
sum('x', 'y');
// error TS2345: Argument of type '"x"' is not assignable to parameter of type 'number'.
TypeScript는 정적 타입을 지원하므로 컴파일 단계에서 오류를 포착할 수 있는 장점이 있다. 명시적인 정적 타입 지정은 개발자의 의도를 명확하게 코드로 기술할 수 있다. 이는 코드의 가독성을 높이고 예측할 수 있게 하며 디버깅을 쉽게 한다.
리팩토링의 영향이 닿는 모든 기능을 확인하기 전에는 확신하기 어려운 자바스크립트와는 달리, (타이핑을 잘했다는 가정하에) 타입스크립트는 컴파일 타임에 어느 부분이 깨지는지 빠짐없이 알려주기 때문에 리팩토링하기 편해지고, 리팩토링에 대해서 열린 마음을 갖게 된다. 결론적으로 타입 에러를 컴파일 타임에 발견해서 얻는 이득은 런타임에서의 안정성보다는 더 좋은 개발경험과 생산성, 그리고 그로 인해 얻게 될 더 좋은 코드에 가깝다.
2) 도구의 지원
IDE(통합개발환경)를 포함한 다양한 도구의 지원을 받을 수 있다는 것이다. IDE와 같은 도구에 타입 정보를 제공함으로써 높은 수준의 인텔리센스(IntelliSense), 코드 어시스트, 타입 체크, 리팩토링 등을 지원받을 수 있으며 이러한 도구의 지원은 대규모 프로젝트를 위한 필수 요소이기도 하다.
3) 유지보수
프론트엔드에서는 SPA의 코드 규모가 MPA보다 크기 때문에 정적 타이핑에 유리하며, 프로젝트가 더 대규모일수록, 그리고 더 장기간 유지보수할 가능성이 높아질 수록 타입스크립트의 장점이 부각된다.
TypeScript는 ES5의 Superset이므로 기존의 자바스크립트(ES5) 문법을 그대로 사용할 수 있다. 또한, ES6의 새로운 기능들을 사용하기 위해 Babel과 같은 별도 트랜스파일러(Transpiler)를 사용하지 않아도 ES6의 새로운 기능을 기존의 자바스크립트 엔진(현재의 브라우저 또는 Node.js)에서 실행할 수 있다.
참고: poiemaweb.com/typescript-introduction hyunseob.github.io/2018/08/12/do-you-need-to-use-ts/
22. 크롬 브라우저 외 ES6 스펙 지원이 되지 않는 브라우저의 경우 개발자로서 해결 방법은?
- Babel을 사용한다. ES6이상의 문법의 코드들을 브라우저가 이해할 수 있게끔 ES5이하의 문법으로 변환할 수 있다.
- Babel이란?
- babel은 컴파일러 인가 ? 트랜스파일러인가?
트랜스파일러이다. 컴파일은 한 언어로 작성된 소스 코드를 다른 언어로 바꾸는것(C-> 어셈블리어)
트랜스파일러는 한언어로 작성된 소스코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환
(C++>C, ES6->ES5)
- babel은 컴파일러 인가 ? 트랜스파일러인가?
2019년 11월 현재, 모던 브라우저(Chrome 61, FF 60, SF 10.1, Edge 16 이상)에서 ES6 모듈을 사용할 수 있다. 단, 아래와 같은 이유로 아직까지는 브라우저가 지원하는 ES6 모듈 기능보다는 Webpack 등의 모듈 번들러를 사용하는 것이 일반적이다.
- IE를 포함한 구형 브라우저는 ES6 모듈을 지원하지 않는다.
- 브라우저의 ES6 모듈 기능을 사용하더라도 트랜스파일링이나 번들링이 필요하다.
- 아직 지원하지 않는 기능(Bare import 등)이 있다. (ECMAScript modules in browsers 참고)
- 점차 해결되고는 있지만 아직 몇가지 이슈가 있다. (ECMAScript modules in browsers 참고)
트랜스파일러(Transpiler) Babel과 모듈 번들러(Module bundler) Webpack을 이용하여 ES6+ 개발환경을 구축하여 보자. 아울러 Webpack을 통해 ES6+ 코드와 Sass를 트랜스파일링하는 방법도 알아볼 것이다.
1) Babel
Babel는 최신 사양의 자바스크립트 코드를 IE나 구형 브라우저에서도 동작하는 ES5 이하의 코드로 변환(트랜스파일링)할 수 있다.
// ES6 화살표 함수와 ES7 지수 연산자
[1, 2, 3].map(n => n ** n);
// ES5
"use strict";
[1, 2, 3].map(function (n) {
return Math.pow(n, n);
});
2) Webpack
의존 관계에 있는 모듈들을 하나의 자바스크립트 파일로 번들링하는 모듈 번들러이다.
Webpack을 사용하면 의존 모듈이 하나의 파일로 번들링되므로 별도의 모듈 로더가 필요없다. 그리고 다수의 자바스크립트 파일을 하나의 파일로 번들링하므로 html 파일에서 script 태그로 다수의 자바스크립트 파일을 로드해야 하는 번거로움도 사라진다.
참고: poiemaweb.com/es6-babel-webpack-2
'Learn then Key points > Tech Interview Questions' 카테고리의 다른 글
7. Network (0) | 2021.03.29 |
---|---|
6. HTTP (0) | 2021.03.29 |
5. Data Structure (0) | 2021.03.29 |
4. Node.js (0) | 2021.03.29 |
2. Web general (0) | 2021.03.29 |