TIL 15일차 - [JavaScript] Koans

Yoon Kyung Park·2023년 5월 1일
0

TIL

목록 보기
15/75

koans는 총 10개 part에 51개의 문제가 있었다.

10개의 part에서 헷갈리거나 틀린 것을 통해 배운 내용을 요약하고자 한다.
문제의 예시들은 조금씩 바꾸었다.
시간은 오래 걸렸지만 도움은 많이 되었다.

2. Types-parts1

  • 숫자 + 문자 = 문자 (이어붙여서 출력) --> 1+'1' = '11' (2 아님)
  • 문자 + 불리언값 = 문자 (이어붙여서 출력) --> '1' + true = '1true' (2 아님)

3. let Const

  • 'const'로 선언된 변수에는 재할당, 재선언 불가
  • 'const'로 선언된 배열에는 새로운 요소를 추가, 삭제할 수 있음.
  • 'const'로 선언된 객체에는 속성을 추가, 삭제할 수 있음.
  • let과 const도 var와 같이 제일 상단으로 변수를 등록하는 호이스팅이 되지만,
    값을 할당하기 전에 참조할 경우, 선언과 초기화가 동시에 일어나는지에 차이가 있다.
    var는 동시에 일어나지만, let과 const는 동시에 일어나지 않는다.
  • let과 const는 둘 다 선언과 초기화가 동시에 일어나지 않는다.
    다만, let은 선언과 할당을 따로 해도 되고, 재할당이 가능한 반면,
    const는 선언과 할당을 동시에 해야 하며, 재할당이 불가하다.

4. scope

  • 함수 선언식과 함수 표현식의 차이를 알 수 있다.
    : 컴퓨터는 코드를 읽을 때, 변수의 선언을 먼저 읽는다.
    변수의 선언을 읽은 후, 초기화 하고, 그 이후 할당된 값을 읽는다.
    이때, var는 값을 할당하기 전에 참조를 할 경우,
    선언과 초기화를 동시에 하여, error가 아닌 undefined가 나온다.
    반면, let과 const는 초기화없이 선언만 이루어지므로
    값을 할당하기 전에 참조를 할 경우, TDZ에 의한 에러가 발생한다.

  • 함수 선언식과 함수 표현식의 차이
let funcExpressed = 'to be a function'; // 재할당함

	expect(typeof funcDeclared).to.equal('function');
    expect(typeof funcExpressed).to.equal('string');
    
    function funcDeclared(){
    return 'this is a function declaration';
    }
    
    funcExpressed = function(){    
    return 'this is a function expression';
    }
    
    const funcContainer = {func : funcExpressed};  // 재할당함
    expect(funcContainer.func()).to.equal('this is a function expression')
    
    funcContainer.func = funcDeclared; 
    
    expect(funcContainer.func()).to.equal('this is a function declaration');
})

따라서 제일 상단에 선언된 funcExpressed와
함수 function funcDeclared(){return 'this is a function declaration'}와
funcContainer를 먼저 읽는다.
이때, 함수는 변수와 달리 함수 실행문까지 모두 읽는다.
여기서 함수는 함수 표현식이 아닌 함수 선언식만 호이스팅 되며,
호이스팅된 함수 선언식은 실행문까지 모두 읽는다.

따라서 제일 상단에 변수로 선언하여 값을 할당한 funcExpressed는 참조하면,
문자열을 출력하고, 함수 funcDeclared()는 함수로 출력한다.

그 다음 {func : funcExpressed}을 할당하라고 선언한 funcContainer에는
funExpressed의 리턴값이 출력되고,
이후 funcContainer에 funcDeclared를 재할당했으므로,
funcDeclared의 리턴값이 출력된다.


  • lexical scope와 closure에 대한 문제
(bts 문제)
이거는 정말 많이 고민했다.
scope와 closure에 대한 개념을 다 포함한 문제이기에 이해하기에는 어려웠지만, 도움이 많이 되었다.

function(){

let age = 32;
let name = 'Jin'; // 'Jimin'으로 재할당
let height = 179;

function outerFn(){
	let age = 29;  // 30으로 재할당
	name = 'Jimin';
	let height = 178;

function innerFn(){
	age = 30;
	let name = 'Rm';
	return height;  // 클로저에 의해 위의 함수의 height의 값을 참조

	innerFn(); // 실행해야 재할당된 값들이 적용됨.

	expect(age).to.equal.(30)
	expect(name).to.equal.('Jimin')

	return innerFn;
}

	const innerFn = outerFn();  
    
    // outerFn 함수를 실행하면 반환값은 innerFn 함수이다. 
    innerFn 함수는 height를 반환한다. 
    따라서 innerFn 변수는 innerFn 함수의 height를 반환한다. 
    원칙은 밖에서 내부 함수의 변수에 접근할 수 없지만, 
    이는 클로저의 특성으로 인해 접근이 가능하다.

	expect(age).to.equal(32)   // 전역 스코프의 나이를 참조
 	expect(name).to.equal('Jimin')  // 전역 스코프의 이름을 참조
	expect(innerFn()).to.equal(178) // innerFn 함수의 반환값을 참조

	});
})

전역 스코프에 선언된 전역 변수들은 Jin에 대한 정보들이다.
지역 스코프에 있는 outerFn 함수에는 Jimin이라는 이름으로 재할당했고,
나이와 키는 지역변수로 선언하여 할당했다.
이는 전역변수와 별개로 outerFn 함수 내에서 작동하는 변수이다.

그 아래 지역 스코프에 있는 innerFn 함수에는 Rm에 대한 정보가 있다.
변수에 없는 값은 클로저에 의해 위의 함수에서 참조할 수 있다.

6. Types-part2

  • 파라미터(매개변수)는 전달인자 모두 변수에 데이터를 할당한다.
  • 함수를 호출하면서 넘긴 전달인자가 호출된 함수의 지역변수로 매 호출 시마다 새롭게 선언된다.
  • 원시 자료형의 데이터를 함수의 전달인자로 전달하는 경우
let currentYear = 2003

function afterTwentyYear(year){ // 매개변수 year은 let year과 같다.
year = year + 20;
}

afterTwentyYear(currentYear); // 리턴이 없으므로 undefined를 출력

expect(currentYear).to.equal(2003) // 변수의 값은 전역 변수에 할당한 2003이다.

function afterTwentyYear2(currentYear){
currentYear = currentYear + 20;
return currentYear;
}

let after20 = afterTwentyYear2(currentYear);

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

expect(currentYear).to.equal(2003); 
expect(after20).to.equal(2023) 
// afterTwentyYear2의 리턴값을 할당했으니 2023이 나옴.

})```

8. object

  • this는 현재 실행 중인 함수가 속한 객체를 참조하는 키워드로 객체 내부의
    다른 프로퍼티를 참조할 수 있으며, 메서드를 호출하는 시점에 결정된다.
    따라서 this는 함수의 호출에 따라서 값이 달라지기도 한다.
  • refObj는 객체를 가리키는 변수이름으로 이 변수를 통해 전달된 객체를 변경할 수 있다.
  • Object.assign()메서드는 객체 복사, 복사된 객체의 속성값을 변경한다.
    하나 이상의 소스 객체의 속성을 타겟 객체로 복사하는 역할을 한다.
    이는 얕은 복사의 한 종류다.
    얕은 복사의 경우 원시자료형은 값 자체가 복사되어 값에 변경이 없지만,
    참조자료형은 참조값이 복사된다.
    이 메서드의 경우 참조는 원본 속성의 참조를 복사하므로 값에 변경이 있다.
    이와 반대로 깊은 복사는 전체의 값이 복사가 되어 새로운 공간을 만드므로 원시값과
    복사본 값에 서로 영향을 미치지 않는다.

9. spread syntax

  • named parameter는 함수를 호출할 때, 인자의 이름을 함께 지정하는 것으로 순서를 맞추지 않아도 호출가능하다. 다만, js는 이를 지원하지 않으므로,
    js에서는 함수 호출 시, 전달인자의 순서가 매우 중요하다.
  • 만약, 매개변수보다 많은 전달인자를 전달하면, 매개변수 만큼만 출력.
    매개변수보다 적은 전달인자를 전달하면, 받지 않은 매개변수의 값은 undefined를 출력.
  • arguments는 함수 내부에서 사용할 수 있는 유사배열객체로 함수 호출 시,
    전달된 인자들의 정보들을 담고 있으나 객체 형태로 인자를 받으므로
    배열 형태로 사용하기 위해서는 Array.from() 또는 연산자 ...을 사용하여야 한다.
  • rest parameter은 함수 정의에서 ...으로 시작하는 매개변수로,
    인잠 목록에서 나머지 인자들을 묶어서 변수에 할당한 것으로 배열로 인자를 받을 수 있으며,
    rest 뒤에 ','로 다른 인자가 올 수 없다.
    마지막 인자까지도 rest에 포함되어 나머지로 묶여 변수에 할당된다.
    따라서 별도로 rest 앞에 지정된 인자 외에는 모두 rest로 묶인다.

10. Destructuring

  • 객체 안에 객체가 중첩되어 있을 경우,
    ...을 사용하여 해당 객체의 속성을 모두 복사하여 가져올 수 있다.
    다만 해당 객체에 다른 값을 재할당 할 때는 rest/spread 문법을 사용한 다음에 재할당해야 한다.
    rest/spread 문법을 사용하기 전에 값을 할당하면,
    새로 할당한 값이 덮어쓰여지지 않고 아래 rest/spread 문법의 값이 저장된다.

소감

🔡➡️💻➡️🤓👍

오늘은 Koans 문제를 다시 살펴보며,
내가 잠시 주춤했던 부분, 몰라서 오래 머물렀던 부분, 헷갈려서 다시 돌아왔던 부분들을
되짚어 보며, 개념을 짧게 정리했다.
이후 라이브세션에서 다시 한 번 정리하니 머릿속에서도 많이 체계화됨을 느꼈다.
물론, 한번에 이해가 다 되고, 나의 것이라고 하기에는 아직 부족하므로
틈틈이 돌아와 들여다보고 또 다시 고민해봐야겠다.
지금까지 학습한 내용 중에 가장 도움이 되었던 활동이었다! 🤩👍

profile
developerpyk

0개의 댓글