JavaScript Koans 7/13

waymo·2022년 7월 13일
0
post-thumbnail

Unit 10

📋 Javascript Koans

페어 분과 javascript koans 문제를 하나 씩 해결하면서 지난시간에 배웠던 개념을 정리하고 몰랐던 내용을 새롭게 알아가는 시간을 가졌다.
헷갈렸던 내용이나 새롭게 알게된 개념을 다시 정리해보려고 한다!

1. 비교 연산자 ===

==은 느슨한 동치 연산(loose equality)

let actualValue = 1 + 1;
let expectedValue = 2;

actualValue === expectedValue // true

===은 엄격한 동치 연산 (strict equality)
값과 타입까지 일치해야 true


2. type

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

type을 풀면서 새롭게 알게된 점은 뺄셈을 할때는 문자열이 숫자로 취급되어 연산이 진행된다는 점이었다. '문자열 숫자'- '문자열 숫자'도 콘솔을 통해 해보니 숫자로 연산되어 출력 되었다.
그리고 true값과 숫자가 연산될때는 1로 취급 된다는 것을 배웠다.


3. const

  • const로 선언된 변수에는 재할당(reassignment)이 금지 된다.
  • const 로 선언된 배열 객체의 경우 새로운 요소, 속성을 추가하거나 삭제할 수 있다.

const 키워드를 사용하면 의도치 않은 재할당을 방지해 주기 때문에 보다 안전하다. 변경이 발생하지 않는(재할당이 필요 없는 상수) 원시 값과 객체에는 const 키워드를 사용한다.
https://poiemaweb.com


4. 스코프

이부분에서는 함수 선언식과 함수 표현식의 호이스팅에 차이에 대해서 배웠다.
함수 선언식으로 작성된 선언식은 선언되기 전에 호출 해도 호이스팅현상으로 인해 에러가 발생하지 않지만, 표현식으로 작성된 함수를 코드가 작성되기전에 호출을 하면 에러가 발생한다.

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

lexical scope 문제를 풀면서 전역 변수가 지역 변수에 의해 가려지는 현상 shadowing에 확실히 알게 되었고, "전역변수보다 지역변수가 더 우선순위를 갖는다"는 개념에 대해 더욱더 이해가 되는 느낌이었다.

function () {
    let age = 27;
    let name = 'jin';
    let height = 179;

    function outerFn() {
      let age = 24;
      name = 'jimin';
      let height = 178;

      function innerFn() {
        age = 26;
        let name = 'suga';
        return height;
      }

      innerFn();

      expect(age).to.equal(26);
      expect(name).to.equal('jimin');

      return innerFn;
    }

    const innerFn = outerFn();

    expect(age).to.equal(27);
    expect(name).to.equal('jimin');
    expect(innerFn()).to.equal(178);
  });
});

클로저 부분이 가장 헷갈리는 부분이 많았다.


5. 화살표 함수

const add = function(x, y) {
  return x + y
}
//화살표 함수로 표현
const add = (x,y) => {
  return x + y
}
// 리턴 생략하기
const subtract = (x, y) => x - y
// 소괄호 붙이기
const multiply = (x,y) => (x * y)
// 파라미터가 하나일 경우 소괄호 생략 가능!
const divideBy10 = x => x / 10
// 화살표 함수로 클로저를 표현하기

const adder = x => {
  return y => {
    return x + y
  }
}

const adder = x => y => x + y

화살표 함수 표현법이 약한 부분이었지만 5번과제를 해결하면서 어느정도는 화살표 함수에 대해 자신감이 생겼다.


6. 원시자료형과 참조자료형

  • 원시 자료형(primitive data type 또는 원시값)은 객체가 아니면서 method를 가지지 않는 아래 6가지의 데이터 string, number, bigint, boolean, undefined, symbol, (null)

  • 원시자료형을 변수에 할당할 경우나, 함수의 전달인자로 전달할 경우 값 자체의 복사가 일어난다.

  • 원시자료형의 데이터는 immutable

  • 원시 자료형이 아닌 모든 것은 참조 자료형 배열([])과 객체({}), 함수(function(){})

  • 참조 자료형에서는 '주소'를 할당하고 그 주소를 참조 한다.

  • 참조 자료형의 데이터는 동적(dynamic)으로 변한다.

  • 원시 자료형의 데이터가 저장되는 공간 (stack)

  • 참조 자료형의 데이터가 저장되는 공간 (heap)

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

nums1 === nums2 // false

배열 값이 같아보여도 데이터의 주소가 다르기 때문에 false 이다.

const num1 = [1, 2, 3]
const num2 = num1

num1 === num2 // true

두 변수는 같은 주소를 저장하고 있기 때문에 true


7. 배열

배열에서는 쉽게 잊어버리고 있었던 slice메서드 사용법과 배열을 함수의 전달인자로 전달하면 , reference가 전달되는 점을 다시 배웠다.

 const arr = ['peanut', 'butter', 'and', 'jelly'];

arr.slice(1)        // ['butter', 'and', 'jelly']
arr.slice(0, 1)     // ['peanut']
arr.slice(0, 2)     // ['peanut', 'butter']
arr.slice(2, 2)     // []
arr.slice(2, 20)    // ['and', 'jelly']
arr.slice(3, 0)     // []
arr.slice(3, 100)   // ['jelly']
arr.slice(5, 1)     // []

8. 객체

객체 첫번째 문제를 빠르게 적고 나서 첫번째 문제는 쉽다고 생각하고 테스트를 돌렸다
테스트에는 틀렸다고 출력되어서 뭐가 문제인지 봤더니 배열같이 생각하고 적었던 메서드length가 문제 였다. length속성은 배열하고 문자열에만 적용된다.
객체에서도 length와 같이 사용하고 싶다면 Object.keys().length 메서드를 사용하면 된다.
this에 대해서도 처음 접했다.

console.log(this === window);

this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다.
자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.

어디서 선언되었는지에 따라 상위 스코프가 결정되는 정적스코프 ,렉시컬 스코프와 다르게 this는 함수가 어떻게 호출되었는지에 따라 달라지는 동적으로 달라진다.

마지막에는 객체에서 중요한 깊은 복사와 얕은 복사의 차이점에 대해서 다뤘다.

얕은 복사 shallow copy

const obj = { mastermind: 'Joker' }
const newObj = obj;

newObj.mastermind = 'James Wood';

console.log(obj.mastermind); // 'James Wood'
console.log(obj === newObj); // true
  • 얕은 복사는 참조(주소)값 복사를 나타낸다. 데이터를 그대로 생성되는게 아닌 데이터 주소값을 복사해서 heap안에 있는 데이터를 서로 공유한다.

깊은 복사 deep copy

const obj = { mastermind: 'Joker' }
const newObj = Object.assign({},obj);

newObj.mastermind = 'James Wood';

console.log(obj.mastermind); // 'Joker'
console.log(obj === newObj); // false
  • 깊은 복사는 값 그자체 복사를 뜻한다. Object.assign({},obj)메소드를 활용하여 객체데이터 깊은복사를 할 수 있다.
  • 하지만 문제에서 나와 있듯이 만약 객체의 프로퍼티 값이 객체 일경우 assign메소드를 이용해 복사를 해도 2차원 객체인 프로퍼티값은 서로 다시 주소를 공유하게 된다. 완벽한 깊은 복사 X

완벽한 깊은 복사 방법은 아직 배우지 않아서 구글선생님을 통해 한번 공부해야겠다.

9. spread 문법

const spread = [1, 2, 3];

const arr = [0, ...spread, 4];

arr // [0, 1, 2, 3, 4]
// 객체 병합
const fullPre = {
      cohort: 7,
      duration: 4,
      mentor: 'hongsik',
    };
const me = {
      time: '0156',
      status: 'sleepy',
      todos: ['coplit', 'koans'],
    };

const merged = { ...fullPre, ...me };
// {cohort: 7, duration: 4, mentor: 'hongsik', time: '0156', status: 'sleepy' , todos: ['coplit', 'Koans']

spread 문법으로 객체의 깊은 복사가 가능하지만 Object.assign과 마찬가지로 2차원 객체는 얕은 복사로 된다는 것을 배웠다.

Rest parameter는 항상 배열! 기억하기


10. 구조분해할당

배열분해

const array = ['code', 'states', 'im', 'course']
const [start, ...rest] = array

start // 'code'
rest // ['states', 'im', 'course']

객체의 단축(shorthand)

const name = '김코딩';
const age = 28;

const person = { name, age, level: 'Junior',}
console.log(person); 
// {name: '김코딩', age: 28, level: 'Junior'}

객체 분해

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

console.log({ name }); 
// { name : '박해커' }
const student = { name: '최초보', major: '물리학과' }
const { name, ...args } = student

console.log(name); // '최초보'
console.log(args); // {major: '물리학과'}

코드를 보면서 쉽게 이해할 수 있어서 다행이였다. 👍

profile
FE 개발자(진)가 되고 싶습니다

0개의 댓글