파게로그

33 Concepts Every JS Developer Should Know 본문

콤퓨타 왕기초/JS

33 Concepts Every JS Developer Should Know

파게 2020. 10. 19. 11:56
const result = add(10, 20);
const add = (a, b) => a+b;
console.log(result); // error

JS 개발자 사이에서는 하나의 성경과 같은 것을 발견했다.

https://github.com/leonardomso/33-js-concepts

한국어 버전은 이건데, 번역이 되어 있는 건 아니고 영어로 된 영상만 링크를 건 것 같다.

https://github.com/yjs03057/33-js-concepts

어쨌든, 몇 가지 헷갈리는 개념들이 있어서 정리해 보았다.


#1. undefined vs null vs NaN

 

undefined: not defined yet

null: defined as 'not exist'

NaN: not a number

let sth;
console.log(sth); // undefined

let nullConst = null;
console.log(nullConst); // null

let wtf = Math.power(5, "hi");
console.log(wtf); // NaN

 

#2. Value types vs Reference types

 

call by value: string, number, boolean, undefined, null, NaN

call by reference: array, object, function

console.log([10]===[10]); // false

 

#3. Type Coercion(feat. == and ===)

 

Javascript converts type of value forcibly when == used.

If === used, type coercion does not happen.

console.log("1"==1); // true
console.log("1"===1); // false

console.log("1"==true); // true (== converts boolean to number)
console.log("true"==true); // false ("true" cannot be converted to number)

console.log(10+true); // 11 (true: 1, false: 0)
console.log(0==false); // true
console.log(10+"true"); // 10true (loaded operator?)
console.log(5+10+"true"); // 15true (read left to right)
console.log(10-"1"); // 9 (parse to integer)

console.log(undefined==true); // false
console.log(undefined==false); // false
console.log(null==true); // false
console.log(null==false); // false
console.log(NaN==true); // false
console.log(NaN==false); // false

if ("") {console.log("executed");} // nothing displayed
if ("hi") {console.log("executed");} // hi

 

#4. typeof

typeof(1) // number
typeof 1 // number

 

중대한 버그가 있다.
참고로 typeof는 primitive type에, instanceof는 Array, Object에 사용한다.

const sthArr = [1, 2, 3];
const sthObj = {name: "Nancy", height: 165};

console.log(typeof(sthArr)); // object
console.log(typeof(sthObj)); // object

// to tell apart array and object
console.log(sthArr instanceof Array); // true
console.log(sthArr instanceof Object); // false
console.log(sthObj instanceof Array); // false
console.log(sthObj instanceof Object); // true

 

#5. Scope

 

let, const는 block scope!
var는 funciton scope... 사용을 지양하자.

 

#6. Expression vs Statement

 

Expression: value를 return하는 무언가.
Statement: variable에 assign될 수 없음(=는 expression을 기대하고 있음).

 

참고로 hoisting이란 모든 declaration을 상단으로 가져오는 것이다.

물론 아래는 불가능하다.

const result = add(10, 20);

function add(a, b) {
    return a+b;
}

console.log(result);

 

#7. IIFE, Modules and Namespaces

 

IIFE

IIFE: Immediately-Invoked Function Expression

예를 들어, 어떤 array는 클라이언트가 브라우저에서 읽거나 수정할 수 있다.

기능은 수행되도록 하되 클라이언트로부터의 접근을 차단하려면 IIFE에 넣는다.

 

(function() {
	const secretUsers = ["David", "Alice", "Jenny"];
    console.log(secretUsers);
})();
// 출력은 가능하지만 console에서 secretUsers를 입력하면 undefined

(() => {
	const secretUsers = ["David", "Alice", "Jenny"];
    console.log(secretUsers);
})();
// 조금 더 나은 디자인

 

Module

webpack, gulp 등 모듈 번들러 없이, 바닐라 자바스크립트로 모듈 합치기를 어떻게 할 수 있을까?

 

HTML에서 js 파일이 모듈이라고 말해준다!

<script type="module" src="app1.js"></script>
<script type="module" src="app2.js"></script>

 

app1.js, app2.js는 각각 다음과 같다.

/* app1.js */
export let users = ["Stephanie", "Aiden", "Logan"];
export const addUser = (user) => users = [...users, user];
// users = [...users, user]
// 이 방식은 값을 돌릴 수 없는 immutable 방식임.
// push를 할 수도 있지만 Nicolas가 함수형 프로그래밍에 꽂혀 있어서 그랬다고 함...
export const getUsers = () => users;
export const deleteUser = (user) => users = users.filter(aUser => aUser !== user);
/* app2.js */
import {users, addUser, getUsers} from "./app1.js";

console.log(getUsers());
addUser("Autumn");
console.log(getUsers());
// 브라우저는 원래 import, export를 이해하지 못하기 때문에 error를 띄움
// 하지만 ES6부터는 HTML에서 모듈임을 말해준다면 정상 실행

 

#8. Message Queue and Event Loop

먼저, blocking 언어와 non-blocking 언어가 있다.

예를 들어 Python은 blocking 언어, JS는 non-blocking 언어이다.

만약 JS가 blocking 언어였다면, 우리는 input에 타이핑을 할 수가 없는데,

JS는 API fetch를 핸들링하느라 바빴을 것이기에 그렇다.

즉 user input, event, fetch 등 무엇이든 한 번에 하나밖에 못하니까.

 

자세한 개념은 다음의 두 링크를 참고하자.

http://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/

https://heecheolman.tistory.com/48

 

다만, 예를 들어 alert는 blocking function이다. 창 뜨면 아무것도 못한다.

alert("Alert!");
console.log("hi");

 

본론으로 돌아와서, 다음과 같은 코드에서 괄호에 넣은 것들은 어디로 가는 것일까?

setTimeout(console.log, 0, "hi");
console.log("bye");
// bye 출력 후 hi 출력

 

Web API는 JS가 default로 가지고 있지 않은, localStorage, setTimout 등의 기능을 수행한다.

fetch의 경우에도 Web API가 웹 사이트를 부르고, 메시지가 Queue로 오고,

그 후 JS가 준비되었을 때 Queue에서 불러서 함수를 실행시킴.

callback, event 등이 있는 건... non-blocking 언어니까 timeout 같은 것을 넣을 곳이 필요하기 때문이다.

setTimout에 대한 설명에서 알 수 있듯, time specific하지 않다.

 

한편 다음과 같은 코드로 setTimeout이나 setInterval에 대한 취소가 가능하다.

const hiT = setTimeout(console.log, 10000, "hi");
console.log(hiT); // ID of Timeout is displayed.
clearTimeout(hiT); // cancel

const helloT = setInterval(console.log, 5000, "hello");
console.log(helloT);
clearInterval(helloT); // cancel

// clearTimeout()이나 clearInterval()에 잘못된 인자가 들어가도 에러가 발생하지는 않는다.

 

#8. requestAnimationFrame

 

animation

사람들은 지금까지 스크린에서 뭔가 움직이게 하려면 setInterval을 사용했다.

하지만 setInterval은 time specific하지 않고, 그리고 CPU나 GPU에 따라서 interval이 늘어날 수 있기에 나빴다.

그러나 requestAnimatioFrame은 브라우저를 다시 렌더링하기 전에 함수를 실행한다.

브라우저가 업데이트 할때마다 animation frame을 요청할 거고, 그래서 애니메이션을 수정할 수 있다.
CPU랑 그래픽카드에 최적화되어 있어서, 다른 탭으로 이동하면 Chrome은 이걸 실행시키지 않는다.

해당 스크린을 페인트하는 게 아니니까! 즉, 뭔가를 최대한 빠르게 실행하고 싶을때 사용한다.

 

requestAnimationFrame(() => console.log("hi"));
// callback은 브라우저 렌더링 이전에 호출된다.
const sayHi = () => {
	console.log("hi");
    requestAnimationFrame(sayHi);
};
requestAnimationFrame(sayHi);

아직 몇 가지 이해되지 않는 부분들은 추가로 검색해보고 보충해두어야겠다.

'콤퓨타 왕기초 > JS' 카테고리의 다른 글

유용한 libs, APIs  (0) 2020.10.15
JSON 다루기  (0) 2020.10.15
DOM에서 element 생성 또는 제거  (0) 2020.10.15
array  (0) 2020.10.15
event, event handlers (2)  (0) 2020.10.12
Comments