SEB FE 42_TIL

[JavaScript] Koans를 풀며 배운 것들 정리

김피치 2022. 11. 9. 16:50

Koans란?
Koans는 불교에서 유래된 단어로, 결론을 내리기 전에 이게 왜 맞는지 깊게 고민한다는 의미를 가지고 있다고 한다.

어떠한 화두를 가지고 고민하며 선문답을 나누며 수행하는 참선법인데, 이런 단어를 자바스크립트를 공부하면서 보게 되니 참신했다.

생각해보면 종교에서 깨달음을 얻기까지 걸리는 고행의 과정이나, 코딩 과정에서 부닥친 문제를 머리를 꽁꽁 싸매가며 해결하는 과정이나 둘 다 수행하는 자의 괴로움이 수반된다는 점에서 본질적으로 영 다른 것만은 아닌 것 같기도 하다.

 

 

Type

1. 느슨한 동치 연산자(==) 사용 지양
  - '=='는 두 값의 일치 여부를 느슨하게 검사하는데, 이는 '=='의 실행 중 타입 변환(type coercion)이 일어나기 때문이다.

  - 이에 따라 프로그램의 작동을 예측하기 어렵게 할 수 있으므로 지양하는 것이 좋다.

 

 

2. 자바스크립트 내 동치 연산의 별난(quirky) 특성

1 + '1' === '11' // true
123 - '1' === 122 // true
1 + true === 2 // true
'1' + true === '1true' // true

(위와 같은 이해하기 어려운 특성 관련된 참고 사이트 https://github.com/denysdovhan/wtfjs)

 

 

3. 원시 자료형은 값 자체에 대한 변경이 불가능(immutable)

  - 새로운 값으로 재할당은 가능

    -> 그러나 원시 자료형 그 자체와 원시 자료형이 할당된 변수는 구분되어야 함

 

 

4. 원시 자료형을 변수에 할당할 경우, 값 자체의 복사가 일어남

 

 

5. 원시 자료형 또는 원시 자료형의 데이터를 함수의 전달인자로 전달할 경우, 값 자체의 복사가 일어남

  - 사실 함수의 전달인자도 변수에 자료(data)를 할당하는 것

  - 함수를 호출하면서 넘긴 전달인자가 호출된 함수의 지역변수로 (매 호출 시마다) 새롭게 선언된다

 

 

6. 참조 자료형의 데이터는 동적(dynamic)으로 변함

  * .length 속성은 string, array 길이를 반환 (object의 길이는 Object.keys(obj) 속성을 이용해 계산)

 

 

7. 참조 자료형을 변수에 할당할 경우, 데이터의 주소가 저장됨

  - 값 자체의 복사가 일어나는 것은 아님

    why? 배열이 얼마나 많은 데이터를 지니고 있는 지 프로그램의 실행 중에 수시로 변경될 수 있어서 일단 주소만 복사하여 동일한 데이터를 바라보게 하는 것이 효율적

const nums1 = [1, 2, 3];
const nums2 = [1, 2, 3];
nums1 === nums2 // false

-> 동일한 데이터를 가지고 있지만 같은 것은 아님.

변수 nums1과 nums2는 실제 배열을 저장하는 것이 아니라 배열 [1, 2, 3]이 저장된 각각 다른 주소를 저장

그래서 변수 nums1이 가진 heap 주소 !== 변수 nums2이 가진 heap 주소 이므로 두 변수는 동일한 것이 아님

 

 


 

선언 키워드 (Let, Const)

1. const로 선언된 변수에는 재할당 금지

  - 재할당은 금지이나 새로운 요소나 속성을 추가, 삭제 가능

 

* (참고) 구글 스타일 가이드_선언 키워드 안내

https://google.github.io/styleguide/jsguide.html#features-use-const-and-let

 

Google JavaScript Style Guide

Google JavaScript Style Guide 1 Introduction This document serves as the complete definition of Google’s coding standards for source code in the JavaScript programming language. A JavaScript source file is described as being in Google Style if and only i

google.github.io

 

 


 

화살표 함수

1. 화살표 함수 사용법

const add = (x, y) => {
      return x + y
    }

const subtract = (x, y) => x - y

const multiply = (x, y) => (x * y)

const divideBy10 = x => x / 10

  - function 키워드 생략하고 화살표 => 를 붙임

  - 리턴 생략 가능

  - 필요에 따라 소괄호 사용

  - 파라미터가 하나인 경우 소괄호 생략 가능

 

 

2. 화살표 함수를 이용해 클로저 표현 가능

function () {
    const adder = x => {
      return y => {
        return x + y
      }
    }

 

 


 

스코프(Scope)

1. 스코프란?

    : scope는 변수의 값(변수에 담긴 값)을 찾을 때 확인하는 곳

 

 

2. 자바스크립트 함수 호이스팅(hoisting)

    : 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것

  * 참고 https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

호이스팅 - 용어 사전 | MDN

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다

developer.mozilla.org

더보기

모든 변수 선언은 호이스팅이 발생한다.

그러나 var 키워드로 선언한 변수만 호이스팅이 발생하는 것으로 보인다. 왜냐하면 let, const 키워드로 선언한 변수는 초기화 단계에 TDZ(Temporary Dead Zone)에 머물고 이때 변수를 참조하면 참조 에러가 발생하기 때문.

 

함수 호이스팅

함수 선언문으로 정의한 함수는 함수 호이스팅(함수 선언 이전에 호출이 됨)이 일어난다.

함수 호이스팅은 좋은 게 아님

호이스팅이 안 일어나는 방향으로 코드를 짜는 것이 좋다

함수 표현식 사용이 권장됨

 

 

3. 클로저 (Closure) 의 정의

    : 클로저는 함수와 함수가 선언된 어휘적 환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.

  - 자바스크립트는 함수가 호출되는 환경과 별개로, 기존에 선언되어 있던 어휘적 환경을 기준으로 변수를 조회함

  - 클로저는 내부(inner) 함수가 외부(outer) 함수의 지역 변수에 접근할 수 있다.

(function factories, namespacing private variables/functions) 찾아볼 것!

더보기

자바스크립트의 함수는 일급 객체

함수는 변수에 할당도 가능, 리턴도 가능, 매개변수로도 넣을 수 있음

 

함수가 함수를 리턴하는 형태가 나오면 클로저라고 의심

리턴되고 있는 함수가 외부 함수의 변수를 참조하면 클로저

  1. 중첩함수(함수가 함수 리턴) 2. 리턴된 함수가 외부함수의 변수 참조

 ? 변수를 안전하게 보호(은닉) -> 리턴된 함수를 사용하지 않으면 다른 요인으로 변수 바꾼다.

 

 


 

배열

1. array 메소드 .slice()

  - arr.slice(0) : arr의 값을 복사하여 새로운 배열을 리턴

 

 

2. Array를 함수의 전달인자로 전달할 경우, reference가 전달됨

 

 


 

객체

1. obj.length 는 undefined를 반환

  - 길이를 알고 싶은 경우에는 Object.keys() 사용

 

 

2. Object 내에 존재하지 않는 속성(키)을 호출하는 경우 undefined 반환

 

 

3. this

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

 

this - JavaScript | MDN

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

developer.mozilla.org

더보기

설명(나중에 수정)

* method는 '어떤 객체의 속성으로 정의된 함수'를 말합니다. 위의 megalomaniac 객체를 예로 든다면,
* getMembers는 megalomaniac 객체의 속성으로 정의된 함수인 '메소드'라고 할 수 있습니다. megalomaniac.getMembers()와 같은 형태로 사용(호출)할 수 있죠.
* 사실은, 전역 변수에 선언한 함수도 웹페이지에서 window 객체의 속성으로 정의된 함수라고 할 수 있습니다.
* window. 접두사 없이도 참조가 가능하기 때문에(window.foo()라고 사용해도 됩니다.), 생략하고 쓰는 것뿐입니다. 이렇듯, method는 항상 '어떤 객체'의 method입니다.
* 따라서 호출될 때마다 어떠한 객체의 method일 텐데, 그 '어떠한 객체'를 묻는 것이 this입니다.
* 예시로, obj이라는 객체 안에 foo라는 메서드를 선언하고, this를 반환한다고 했을 때 ( 예: let obj = {foo: function() {return this}}; )
* obj.foo() === obj 이라는 코드에 true라고 반환할 것입니다.
* this는 함수의 호출에 따라서 값이 달라지기도 합니다. (apply나 call, bind에 대해서는 하단의 학습자료를 통해 더 공부해 보세요.)
*
* 그러나 화살표 함수는 다릅니다. 자신의 this가 없습니다.
* 화살표 함수에서의 this는 자신을 감싼 정적 범위(lexical context)입니다. (전역에서는 전역 객체를 가리킵니다.)
* 일반 변수 조회 규칙(normal variable lookup rules)을 따르기 때문에, 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수 바로 바깥 범위에서 this를 찾습니다.
* 그렇기에 화살표 함수를 사용할 때, 이러한 특이점을 생각하고 사용해야 합니다.

 

 

4. Object를 함수의 전달인자로 전달할 경우, reference가 전달됨

  - 'Object.assign'을 통한 복사는 reference variable은 주소만 복사한다

(참고) 얕은 복사shallow copy vs. 깊은 복사deep copy

https://scotch.io/bar-talk/copying-objects-in-javascript

 

DigitalOcean

Technical tutorials, Q&A, events — This is an inclusive place where developers can find or lend support and discover new ways to contribute to the community.

www.digitalocean.com

https://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

 

 


 

전개 문법 (Spread Syntax)

1. 빈 배열에 전개 문법 사용 시 아무것도 전달되지 않음

 

 

2. 여러 개의 배열을 이어붙일 수 있음

const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
concatenated = [...arr1, ...arr2];
return concatenated; // [0, 1, 2, 3, 4, 5]

  - cf) arr1.concat(arr2)

 

 

3. 여러 개의 객체도 병합 가능

 

 

4. Rest Parameter는 함수의 전달인자를 배열로 다룰 수 있게 함

  - 자바스크립트는 named parameter를 지원하지 않기 때문에 함수 호출 시에 전달인자의 순서가 중요함

  - rest parameter는 spread syntax를 통해 간단하게 구현 가능

  cf) 전개 문법 도입 이전에는 arguments를 통해 비슷하게 함수의 전달인자를 다룰 수 있음.

        그러나 arguments는 모든 함수의 실행 시 자동으로 생성되는 '객체' (배열과 매우 흡사하지만 아님)

 

 

5. Rest Parameter는 전달인자의 수가 정해져 있지 않은 경우에도 사용 가능 

  function sum(...nums) {
      let sum = 0;
      for (let i = 0; i < nums.length; i++) {
        sum = sum + nums[i];
      }
      return sum;
    }

 

 

6. Rest Parameter는 전달인자의 일부에만 적용할 수도 있음

  - rest parameter는 항상 배열

 

 


 

구조분해 할당(Destructuring Declaration)

1. 배열을 분해함

 const array = ['hello', 'from', 'the', 'other', 'side']

    const [first, second] = array
    first // 'hello'
    second // 'from'

 

 

2. rest/spread 문법을 배열 분해에 적용할 수 있음

  - but 할당하기 전 왼쪽에는, rest 문법 이후에 쉼표가 올 수 없습니다

    ex. const [first, ...middle, last] = array (X)

 

 

 

3. 객체를 분해함

 const student = { name: '박해커', major: '물리학과' }

    const { name } = student // student.name
    name // '박해커'

 

 

4. rest/spread 문법을 객체 분해에 적용할 수 있음

const student = { name: '최초보', major: '물리학과' }
    const { name, ...args } = student

    name // '최초보'
    args // {major: '물리학과'}