본문 바로가기
Javascript

JavaScript 기술을 향상시키는 12 가지 개념

by F.E.D 2020. 6. 21.

요즘 morioh.com 블로그에서 매우 유용한 글들을 많이 찾아볼 수 있어서 좋습니다.

포스팅을 한번 할 때마다 유용한 지식들이 습득되는 것 같아서 더 좋구요.

 

이번에는 javascript 기술을 향상시키는 12가지 개념에 대해서 알아보도록 합시다.

 

자바스크립트는 깊이 들어갈 수록 복잡한 언어입니다.

단순히 자바스크립트 개발자가 된다는 것은 자바스크립트 언어를 집요하게 기본 동작 원리를 알아가는 것이 필수 덕목이라고 생각합니다.

 

하루빨리 레거시한 코드와 기본 동작 원리를 깨우치지 못한 상태의 코드들을 개선하고 싶습니다.

그리고 jquery의 종말과 함께 바닐라 스크립트로 구성할 수 있는 모든 종류의 앱들을 환영하고 받아들일 준비가 되어 있어야 할 것입니다.

 

다양한 팁들을 지속적으로 업데이트 하고 있는 github repository를 fork하여 공유합니다.

https://github.com/oinochoe/javascript-tips-and-tidbits

 

oinochoe/javascript-tips-and-tidbits

A continuously-evolving compendium of javascript tips based on common areas of confusion or misunderstanding. - oinochoe/javascript-tips-and-tidbits

github.com

fork란 다른 사람의 repository를 복사본을 떠서 pull request와 같은 contributor로 활동할 수 있는 여지와 다른 기능 develop을 위해 존재하는 기능이라고 할 수 있겠습니다.

 

그럼 본론으로 들어가시죠!

 

1. 값 할당 vs 참조 할당 비교

JavaScript가 변수에 할당되는 방식을 이해하는 것은 버그가없는 JavaScript를 작성하는 것에 있어 기본입니다. 

이것을 이해하지 못하면 의도치 않게 값을 변경하는 코드를 쉽게 작성할 수 있습니다.

 

JavaScript는 항상 기본적으로 값으로 변수를 할당합니다.

특히 JavaScript 기본 유형인 Boolean, null, undefined, String, and Numbe는 원시값인 값으로 할당하게 되어있습니다.

그러나 할당 된 값이 Array, Function 또는 Object 인 경우 메모리의 객체에 대한 참조가 할당됩니다.

// 값 할당
let var1 = 'My string';
let var2 = var1;

var2 = 'My new string';

console.log(var1);
// 'My string'
console.log(var2);
// 'My new string'

// 참조 할당
let var1 = { name: 'Jim' }
let var2 = var1;

var2.name = 'John';

console.log(var1);
// { name: 'John' }
console.log(var2);
// { name: 'John' }

primitive(원시) 할당과 같은 동작을 예상한 경우 이것이 어떻게 문제를 일으킬 수 있는지 알 수 있습니다.

의도하지 않게 객체를 변경하는 함수를 만들면 특히 매우 좋지 않을 수 있습니다.

 

2. 클로저

클로저는 변수에 개인 액세스를 제공하는 중요한 JavaScript 패턴입니다.

이 예에서 createGreeter는 제공된 인사말 "Hello"에 액세스 할 수있는 익명 함수를 반환합니다.

향후 모든 용도에 대해 sayHello는이 인사말에 액세스 할 수 있습니다.

function createGreeter(greeting) {
  return function(name) {
    console.log(greeting + ', ' + name);
  }
}

const sayHello = createGreeter('Hello');
sayHello('Joe');
// Hello, Joe

보다 실제적인 시나리오에서는 API 키를 사용하는 일부 메서드를 반환하는 초기 함수 apiConnect (apiKey)를 구상 할 수 있습니다. 

이 경우 apiKey는 한 번만 제공하면되고 다시는 제공하지 않아도됩니다.

function apiConnect(apiKey) {
  function get(route) {
    return fetch(`${route}?key=${apiKey}`);
  }

  function post(route, params) {
    return fetch(route, {
      method: 'POST',
      body: JSON.stringify(params),
        headers: {
          'Authorization': `Bearer ${apiKey}`
        }
      })
  }

  return { get, post }
}

const api = apiConnect('my-secret-key');

// No need to include the apiKey anymore
api.get('http://www.example.com/get-endpoint');
api.post('http://www.example.com/post-endpoint', { name: 'Joe' });

3. 구조화 할당(destructuring)

const obj = {
  name: 'Joe',
  food: 'cake'
}

const { name, food } = obj;

console.log(name, food);
// 'Joe' 'cake'

위와 같이 obj 객체의 키 값을 변수로 바로 할당할 수 있습니다. 

멋지죠?

 

다른 이름으로 특성을 추출하려는 경우 다음 형식을 사용하여 특성을 지정할 수 있습니다.

const obj = {
  name: 'Joe',
  food: 'cake'
}

const { name: myName, food: myFood } = obj;

console.log(myName, myFood);
// 'Joe' 'cake'

다음 예제에서는 destructuring을 사용하여 person 객체를 introduce 함수에 깔끔하게 전달합니다.

다시 말해, destructuring은 함수에 전달 된 매개 변수를 추출하는데 직접 사용될 수 있습니다.

React에 익숙하다면 아마도 전에 본 적이있을 것입니다!

const person = {
  name: 'Eddie',
  age: 24
}

function introduce({ name, age }) {
  console.log(`I'm ${name} and I'm ${age} years old!`);
}

console.log(introduce(person));
// "I'm Eddie and I'm 24 years old!"

4. 전개 연산자(spread syntax)

스프레드 연산자는 비교적 간단합니다! 다음과 같은 경우 Math.max는 배열을 인수로 사용하지 않고 개별 요소를 인수로 사용하므로 arr 배열에 적용 할 수 없습니다. 스프레드 연산자 (...)는 개별 요소를 배열에서 꺼내는 데 사용됩니다.

const arr = [4, 6, -1, 3, 10, 4];
const max = Math.max(...arr);
console.log(max);
// 10

5. Rest 문법

function myFunc(...args) {
  console.log(args[0] + args[1]);
}

myFunc(1, 2, 3, 4);
// 3

6. 배열 메서드 

JavaScript array 메소드 map, filter, reduce와 관련하여 약간의 혼동이 있습니다.

배열을 변환하거나 집계 값을 반환하는 데 유용한 방법입니다.

map : 각 요소가 함수에 의해 지정된대로 변환되는 배열을 반환

const arr = [1, 2, 3, 4, 5, 6];
const mapped = arr.map(el => el + 20);

console.log(mapped);
// [21, 22, 23, 24, 25, 26]

filter : 함수가 true를 반환하는 요소의 배열을 반환

const arr = [1, 2, 3, 4, 5, 6];
const filtered = arr.filter(el => el === 2 || el === 4);

console.log(filtered);
// [2, 4]

reduce : 함수에 지정된대로 값을 누적

const arr = [1, 2, 3, 4, 5, 6];
const reduced = arr.reduce((total, current) => total + current);

console.log(reduced);
// 21

배열 메소드 find, findIndex 및 indexOf는 종종 병합 될 수 있습니다. 다음과 같이 사용하십시오.

find : 지정된 기준과 일치하는 첫 번째 인스턴스를 반환합니다. 

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const found = arr.find(el => el > 5);

console.log(found);
// 6

findIndex : 첫 번째 일치 요소를 반환하는 대신 첫 번째 일치 요소의 인덱스를 반환합니다. 

const arr = ['Nick', 'Frank', 'Joe', 'Frank'];
const foundIndex = arr.findIndex(el => el === 'Frank');

console.log(foundIndex);
// 1

indexOf : findIndex와 거의 동일하게 작동하지만 함수를 인수로 사용하는 대신 간단한 값을 사용합니다. 

const arr = ['Nick', 'Frank', 'Joe', 'Frank'];
const foundIndex = arr.indexOf('Frank');

console.log(foundIndex);
// 1

push, pop, shift, unshift 처럼 배열에서 요소를 대상으로 추가하거나 제거하는 데 도움이되는 훌륭한 배열 방법이 많이 있습니다.

push : 배열의 끝에 항목을 추가

let arr = [1, 2, 3, 4];
const pushed = arr.push(5);

console.log(arr);
// [1, 2, 3, 4, 5]
console.log(pushed);
// 5

pop :마지막 항목 제거

let arr = [1, 2, 3, 4];
const popped = arr.pop();

console.log(arr);
// [1, 2, 3]
console.log(popped);
// 4

shift 및 unshift는 push와 pop의 반대로 작동하므로 생략합니다.

spice, slice는 새로운 서브셋 배열을 리턴합니다.

splice : 기존 요소를 제거 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경

const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "June"]

months.splice(4, 1, 'May');
// replaces 1 element at index 4
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "May"]

slice : 지정된 시작 위치에서 지정된 종료 위치 이전에 배열의 얕은 복사본을 반환
종료 위치를 지정하지 않으면 나머지 배열이 반환됩니다

let arr = ['a', 'b', 'c', 'd', 'e'];
const sliced = arr.slice(2, 4);

console.log(sliced);
// ['c', 'd']
console.log(arr);
// ['a', 'b', 'c', 'd', 'e']

sort : 첫 번째 요소와 두 번째 요소 인수를 취하는 제공된 함수를 기반으로 배열을 정렬합니다

let arr = [1, 7, 3, -1, 5, 7, 2];
const sorter = (firstEl, secondEl) => firstEl - secondEl;
arr.sort(sorter);

console.log(arr);
// [-1, 1, 2, 3, 5, 7, 7]

7. Generators

* 를 두려워하지 말고 사용하세요. next()가 다음에 호출될 때 생성되는 값을 지정합니다.

function* greeter() {
  yield 'Hi';
  yield 'How are you?';
  yield 'Bye';
}

const greet = greeter();

console.log(greet.next().value);
// 'Hi'
console.log(greet.next().value);
// 'How are you?'
console.log(greet.next().value);
// 'Bye'
console.log(greet.next().value);
// undefined


function* idCreator() {
  let i = 0;
  while (true)
    yield i++;
}

const ids = idCreator();

console.log(ids.next().value);
// 0
console.log(ids.next().value);
// 1
console.log(ids.next().value);
// 2
// etc...

8. === vs ==

JavaScript에서 식별 연산자 (===)와 항등 연산자 (==)의 차이점을 알아야합니다.

== 연산자는 값을 비교하기 전에 형식 변환을 수행하지만 === 연산자는 비교하기 전에 형식 변환을 수행하지 않습니다.

console.log(0 == '0');
// true
console.log(0 === '0');
// false

9. 객체 비교

JavaScript 초보자가 실수하는 것은 객체를 직접 비교하는 것입니다.

변수는 객체 자체가 아닌 메모리의 객체에 대한 참조를 가리키고 있습니다.

실제로이를 비교하는 한 가지 방법은 객체를 JSON 문자열로 변환하는 것입니다.

이것은 단점이 있습니다 : 객체 속성 순서는 보장되지 않습니다!

객체를 비교하는보다 안전한 방법은 깊은 객체 비교를 전문으로하는 라이브러리를 가져 오는 것입니다 (예 : lodash의 isEqual).

다음 객체는 동일하게 보이지만 실제로 다른 참조를 가리키고 있습니다.

const joe1 = { name: 'Joe' };
const joe2 = { name: 'Joe' };

console.log(joe1 === joe2);
// false

반대로, 하나의 객체가 다른 객체와 동일하게 설정되어 동일한 참조를 가리키기 때문에 다음은 참으로 평가됩니다 (메모리에는 객체가 하나뿐 임).

const joe1 = { name: 'Joe' };
const joe2 = joe1;

console.log(joe1 === joe2);
// true

10. 콜백 함수

너무 많은 사람들이 JavaScript 콜백 함수에 위협을받습니다.

간단합니다.

이 예를 보십시오.

console.log 함수가 myFunc에 콜백으로 전달되고 있습니다.

setTimeout이 완료되면 실행됩니다. 그게 다야!

function myFunc(text, callback) {
  setTimeout(function() {
    callback(text);
  }, 2000);
}

myFunc('Hello world!', console.log);
// 'Hello world!'

11. 프로미스

JavaScript 콜백을 이해하면 곧 "콜백 지옥"에 빠지게됩니다. 

이것이 Promise의 도움입니다!

Promise에서 비동기를 처리하고 성공하면 Resolve 실패하면 Reject 합니다.

“then”을 사용하여 성공과 실패를 처리하세요.

const myPromise = new Promise(function(res, rej) {
  setTimeout(function(){
    if (Math.random() < 0.9) {
      return res('Hooray!');
    }
    return rej('Oh no!');
  }, 1000);
});

myPromise
  .then(function(data) {
    console.log('Success: ' + data);
   })
   .catch(function(err) {
    console.log('Error: ' + err);
   });

// If Math.random() returns less than 0.9 the following is logged:
// "Success: Hooray!"
// If Math.random() returns 0.9 or greater the following is logged:
// "Error: On no!"

12. Async Await

Promise를 지정하고 기다릴 수 있습니다. 

그 사이사이에 유용한 기능들을 만들고 실행할 수 있습니다.

const greeter = new Promise((res, rej) => {
  setTimeout(() => res('Hello world!'), 2000);
})

async function myFunc() {
  const greeting = await greeter;
  console.log(greeting);
}

myFunc();
// 'Hello world!'

이 12 가지 개념 중 하나라도 모른다면 JavaScript에 대한 지식이 조금이라도 커졌을 것입니다. 

그리고 당신이 12가지 모두를 알고 있다면, 이것이 당신의 지식을 연습하고 키울 수있는 기회였기를 바랍니다.

또 추가적으로 더 중요한 개념이 있다면 댓글로 남겨주세요~!

 

출처 : https://morioh.com/p/05b4ab6bbcb4?f=5c21fb01c16e2556b555ab32

 

'Javascript' 카테고리의 다른 글

[javscript] 12가지 Array 팁  (0) 2020.06.28
Constructor vs Literal  (0) 2020.06.22
Vue.js 12가지 모범사례  (0) 2020.05.03
[JS] Javascript 스트링 메서드  (0) 2020.05.02
Async / Await 주의해서 다루기  (0) 2020.04.25

댓글