출처: https://bumcrush.tistory.com/182 [맑음때때로 여름]
첫 1주는 Javascript에 집중한다. JS를 제대로 모르고 상태로 react와 node를 공부해봐야 기술부채만 쌓여간다. 항상 기본이 중요하다. 이 1주동안 javascript.info page와 러닝 자바스크립트 책을 정독하며 내가 몰랐던 부분과 중요하다고 생각이 드는 부분들을 이곳에 정리한다. (#FFFF00 형광색 색상 코드!!!)
1. Javascript에서 함수는 반드시 return 값을 가져야 한다.
2. 함수의 naming을 할 때는 동사를 접두어로 붙여 함수를 만드는 것이 관습이다.
ex) showMessage(), getAge(), calcSum(), createForm(), ...
함수의 이름을 지을 때 함수 이름에 언급되어 있는 동작들만을 정확히 수행하여야 한다. 그 이외의 동작을 수행한다면 naming을 사실상 할 이유가 없다.
project에서 naming만 잘해도 architecture의 절반 이상을 먹고 들어간다고 한다. 다른 것들도 연습해서 100%가 된다면 좋겠지만 항상 가장 기본적인 것이 가장 중요하다. 변수 하나, 함수 하나의 이름을 짤 때에도 이 이름을 보고 바로 이 변수 혹은 함수가 하는 일을 예측할 수 있게 만드는 naming sense를 갖추는 것이 중요하다.
3. 함수 표현식 vs 함수 선언문
//함수 선언문
function foo(a, b) {
return a + b;
}
//함수 표현식
let foo = function(a, b) {
return a + b;
};
먼저, 식과 문을 구문하는 가장 큰 외관상의 차이는 semi column(;)의 유무 이다. 식의 마무리는 반드시 semi column인 반면 문의 마무리에서는 semi column을 사용하지 않는다.(문은 대표적으로 if문, while문 같은 것들이 있을 수 있다.)
내부적으로는, 함수 표현식은 실제 흐름이 해당 함수에 도달했을 때 함수를 생성하는 반면, 함수 선언문은 함수 선언문이 정의되기도 전에 호출이 가능하다.
함수 표현식에서의 함수 생성 시기는 상식적으로 당연한 반면, 함수 선언문에서의 함수 생성 시기는 상식 밖이다.
이것이 가능한 이유는 자바스크립트 내부 알고리즘에 의해 스크립트를 실행하기 전, 준비단계에서 전역에 선언된 함수 선언문들을 찾고, 해당 함수들을 생성하기 때문이다. 즉, 스크립트가 진짜 실행되기 전 초기화 단계에서 함수 선언 방식으로 정의한 함수가 생성되는 것이다.
//javascript.info에 있는 예제
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
sayHi("John"); // error!
let sayHi = function(name) { // (*) 마술은 일어나지 않습니다.
alert( `Hello, ${name}` );
};
그 다음으로 볼 차이점은, scope이다.
함수 선언문이 코드 블록 내에 위치하면 해당 함수는 블록 내 어디서든 접근할 수 있다. 하지만, 블록 밖에서는 함수에 접근하지 못한다.
반면에 표현식에서는 블록 밖에서도 블록 내부에 존재하는 함수 속의 함수, 객체, 변수 모두에 접근이 가능하다. 이것을 클로저(closure)라고 한다.
(함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 경우를 클로저라 한다.)
(러닝 자바스크립트 p.196)
let globalFunc;
{
let blockVar='a';
globalFunc=function(){
console.log(blockVar);
}
}
globalFunc(); //'a'
globalFunc는 블록 안에서 할당을 받았기 때문에, 이 블로 스코프와 부모인 전역 스코프가 하나의 클로저를 생성한다. 이 클로저 덕분에 어디서든 블록 스코프 내부의 식별자에 접근이 가능해진다.
스코프의 범위를 유지하고 싶을 때 이 클로저 개념과 즉시실행함수를 함께 이용한다.(ES6에서 블록 스코프 변수를 도입하면서 즉시 실행 함수의 사용 빈도가 엄청나게 떨어지긴 했다.)
이곳에 이 둘을 함께 사용하는 예제가 되게 잘 설명 되어 있어서 참고하면 좋을 것 같다.
스코프와 실행컨텍스트
poiemaweb.com/js-execution-context
모던자바스크립트에 따르면 함수 표현식 보다는 함수 선언문을 먼저 고려하는 것이 좋다고 말한다.
항상 리액트의 component와 그 속의 함수들을 정의할 때 함수 선언문으로 해야할까 아니면 arrow function을 이용한 함수 표현식으로 해야 할까 고민하곤 했었다.
최근에 velopert님의 블로그에서 함수 선언문으로 component를 작성하는 것이 아주 조금의 성능적 이점을 갖는다는 내용을 본 이후로는 항상 선언문으로 작성하려 노력했다. 나에게 있어서 이 글은 더더욱 함수 선언문을 사용하여야 하는 계기가 되었다. 특별한 이유가 없다면 항상 함수는 선언문으로 작성하던 노력을 이어가야겠다.
3. 함수의 호출과 참조
getGreeting(); // "Hello, World!"
getGreeting; // function getGreeting()
위에는 함수 호출, 아래는 함수 참조(reference)이다.
함수를 호출하지 않고 참조할 수 있다는 특징은 자바스크립트를 굉장히 유연한 언어로 만들어준다.
const f = getGreeting;
f(); // "Hello, World!" 와 같은 실행이 가능하다.
react에서도 이런 기능이 유용하게 쓰이는데
onClick={onClick} //위에 onClick function을 정의해놨다고 가정.
와 같이 자주 쓰인다. 저번에 리액트 공부를 할 때 이 함수의 호출과 참조를 모르고 onClick={onClick} 이런 식으로 구현하니까 아무 생각없이 onClick={onClick(paremater)} 이런 식으로 구현해버린 적이 있다. 이렇게 하면 함수 참조가 아닌 호출이기 때문에 rendering process에서 지 혼자 실행돼버리고, 이 버튼은 더이상 동작하지 않게 된다. parameter가 없는 경우 저런식으로 함수 참조 기능을 이용해 간단히 적을 수 있지만 parameter가 있는 경우
onClick={()=>onClick(parameter)} 이런 식으로 만들어 click event가 발생했을 때 onClick function이 작동하도록 만들어야 한다.
4. this 키워드와 apply, call, bind
velog.io/@josworks27/%ED%95%A8%EC%88%98%ED%98%B8%EC%B6%9C-call-apply-bind-%EC%B0%A8%EC%9D%B4
예제 코드는 일단 이곳에 있는 코드를 보면 좋을 것 같다.
먼저, 까다로운 this에 대해 알아야 한다. (예제 출처 - 러닝 자바스크립트 p.177)
const o = {
name: 'Wallace',
speak() {return `My name is ${this.name}!`},
}
o.speak();
o.speak()를 실행하면 우리가 원했던 결과인 My name is Wallace가 나온다. 여기서 this 값이 o에 묶인 이유는 o에서 speak를 호출 했기 때문이다.
const speak = o.speak;
speak === o.speak; //true
speak();
speak()의 결과는 My name is undefined 이다. this가 어디에 속하는 지 알 수 없기 때문에 이런 결과가 나온다.
이를 해결하기 위해서 객체 속에 변수를 만들고 이 변수에 this를 할당한다. 하지만, 이는 굉장히 까다로운 일이기 때문에 이를 해결하기 위해 apply, call, bind 같은 함수들을 사용한다.(러닝 자바스크립트 p.183부터) 하지만, 이 조차도 굉장히 까다로운 일이다. 일일이 bind를 적고 그 bind된 객체를 파악하고 있는 일은 결코 쉬운 일이 아니다.
이를 해결할 가장 좋은 방법은 arrow function이다. arrow function은 lexical context이다. (일반 함수는 Execution context) 일반 함수에서는 this의 값이 달라질 수 있기 때문에 반드시 bind해야 하지만 arrow function은 lexical context이기 때문에 bind하지 않아도 this 값이 변하지 않는다.
사실상 react hook을 쓰다보면 this를 사용할 일은 거의 없다. 하지만, 이 자바스크립트 개념은 굉장히 중요한 개념이기 때문에 면접에서도 나올 수 있는 개념이다. 잘 알고 있어야 한다.
5. Javascript의 garbage collector
자바스크립트에는 garbage collector가 존재한다. 이 garbage collector는 더 이상 쓸모가 없는 원시값, 객체, 함수 등을 자동으로 날려줘서 memory 공간을 확보한다. 따라서, 개발자가 직접 이 공간을 확보하기 위해 시간을 쓰지 않아도 된다.
ko.javascript.info/garbage-collection
자바스크립트가 어떻게 공간을 확보하는지 잘 설명되어 있다. 그냥 가볍게만 읽어봐도 되지 않을까 싶다.
www.youtube.com/watch?v=vZRmCbl871I
garbage collector를 이해하기 좋은 영상이라 생각한다.
6. 배열 자체를 수정하는 배열 메서드와 새 배열을 반환하는 메서드 구분
리액트에서는 불변성 유지를 위해 반드시 새 배열을 반환하는 즉 side effect가 없는 method를 써야 한다.
배열 자체를 수정하는 메서드 => push, pop, shift(배열의 처음에 요소를 제거), unshift(배열의 처음에 요소를 추가), splice, fill, reverse
새 배열을 반환하는 메서드 => concat, slice(배열의 일부를 가져오는 slice method는 새 배열을 봔환하지는 않지만 기존 배열을 수정하지 않기 때문에 이곳에 넣었다. 기본적으로 side effect가 없기 때문에.), map, filter, reduce
새 배열을 반환하는 메서드들은 반드시 기억하고 활용해야 한다.
Week6(JavaScript) (0) | 2020.10.28 |
---|---|
Week5(Javascript) (0) | 2020.10.17 |
Week4(Javascript) (0) | 2020.10.11 |
Week3(Javascript) (0) | 2020.10.02 |
Week2(Javascript) (0) | 2020.09.24 |
댓글 영역