TIL - 잡다한 자바스크립트 기본지식 2

sway3·2023년 6월 3일
0

TIL

목록 보기
4/4
post-thumbnail

오늘 새로 배운 내용을 간단하게 공부하여 적는 공간으로 잘못된 정보가 포함되어있을 수가 있습니다.

1. 구조 분해 할당

프로그래머스 lv0 - 구조 분해 할당 문제를 풀고 공부하게 되었다.

구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수로 담을 수 있게 하는 표현식이다.

solution = (box, n) => ~~(box[0]/n) * ~~(box[1]/n) * ~~(box[2]/n);

위의 코드는 필자가 구조 분해 할당 문제를 푼 코드이다.

box 는 총 세 개의 원소를 가진 배열인 매개변수로, box[0], box[1], box[2] 처럼 index 를 활용하여 box 의 원소에 접근하고 있다.

한줄로 코드를 제출한다면 위의 코드도 문제는 없겠지만, 추후에 프로젝트를 할 때나 문제를 풀이하는 코드의 양이 늘어나게 된다면 구조 분해 할당을 활용하여 좀 더 가독성 있고 간결하게 작성할 수 있을 것 같다.

var foo = ["one", "two", "three"];

var [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"

foo 배열을 분해하여 원소들을 red, yellow, green 에 순차적으로 할당한 것을 볼 수 있다.

var a, b;
[a, b] = [1, 2];

위와 같이 변수의 선언이 분리되어도 값이 잘 할당된다.

var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

위와 같이 분해한 값이 undefined 라면 미리 설정해둔 기본값을 할당하게 할 수도 있다.

구조 분해를 활용하여 필자의 코드를 바꿔보도록 하자.

solution = (box, n) => {
	const [width, length, height] = box;
  
	return ~~(width/n) * ~~(length/n) ** ~~(width/n);
}

코드 자체는 길어졌지만 가독성이 눈에 띄게 좋아진게 보인다.

2. String 메소드 모음

프로그래머스 코테 문제풀이를 하며 새로 배운 String 메소드들을 정리해보겠다.

2-1. String.repeat()

repeat(count);

repeat 은 문자열 타입을 count 의 수만큼 반복하여 리턴해주는 메서드이다. 원래의 문자열은 바뀌지 않으니 참고하자.

let str = 'hello';
console.log(str.repeat(0)); // ''
console.log(str.repeat(3)); // 'hellohellohello'
console.log(str.repeat(2.6)); // 'hellohello'

repeat 의 매개변수 count 는 숫자 타입을 인자로 받는데, 이때 실수가 인자로 전달되면 소수점은 버림되어 처리된다.

0 을 인자로 받으면 빈 문자열을 반환한다.

2-2. String.endsWith()

endsWith(searchString)
endsWith(searchString, endPosition)

endsWith 은 문자열 타입이 searchString 로 끝나는지 평가하고 불리언 타입을 반환하는 메소드이다.

아래의 코드를 예시로, 'hello' 는 'llo' 로 끝나기 때문에 true 를, 'el' 로 끝나지 않기 때문에 false 를 반환한다.

let str = 'hello';
console.log(str.endsWith('llo')); // true
console.log(str.endsWith('el')); // false
console.log(str.endsWith('llo', 5)) // true
console.log(str.endsWith('llo', 6)) // false

매개변수 endPosition 은 필수로 값을 전달해야하는 매개변수는 아니지만, 만약 전달해야한다면 string.length 의 값을 전달해야만 true 를 반환한다.

string.length 이 아닌 값을 전달한다면 searchString 으로 문자열이 끝난다고 하더라도 false 를 반환한다.

2-3. String.trim()

trim()

trim 은 문자열의 시작과 끝에 존재하는 모든 공백을 잘라낸 문자열을 리턴한다. 마찬가지로 원래의 문자열을 변경하지는 않는다.

let str = '       Hello World    ';
console.log(str.trim()); // 'Hello World'

시작과 끝의 공백만 잘라내지 중간에 존재하는 공백을 잘라내지는 않으니 참고하자.

3. 연산자 모음

String 메소드 모음과 마찬가지로, 프로그래머스 코테 문제풀이를 하며 새로 배운 연산자들을 정리해보겠다.

3-1. << (왼쪽 시프트 연산자)

a << b

왼쪽 시프트 연산자 << 는 왼쪽 피연산자의 값을 2진수로 바꾼 후, 오른쪽 피연산자 값의 비트만큼 왼쪽으로 이동시킨다.

	 9 (10진수): 00000000000000000000000000001001 (2진수)

9 << 2 (10진수): 00000000000000000000000000100100 (2진수) = 36 (10진수)

위와 같이, 왼쪽 피연산자인 9의 비트가 오른쪽 피연산자의 값인 2만큼 왼쪽으로 이동한 것을 볼 수 있다. 왼쪽으로 이동된 초과된 비트는 폐기되며, 오른쪽은 움직인 만큼 '0' 비트로 채워진다.

a << b
--> a * 2 ** b

위처럼 a << ba * 2 ** b 의 값을 리턴한다.

따라서, 프로그래머스 lv0 - 세균 증식 문제는 비트 연산자를 통해 다음과 같이 간결하게 풀 수 있다.

const solution = (n, t) => n << t;

3-2. ^ (XOR 연산자)

깊게 들어가면 조금 어려운 내용이 될 것 같아 간단하게만 짚고 넘어가겠다. 추후에 연산자를 더 공부하게 되면 그때 자세히 공부해보도록 하겠다.

XOR 연산자는 x 와 y 가 둘다 true 면 false 를, 둘다 false 면 true 를 반환한다. 이 특성을 이용하여 프로그래머스 lv0 - 배열의 길이에 따라 다른 연산하기 문제를 간단하게 해결할 수 있다.

const solution = (arr, n) => (arr.length % 2 === 0) 
	? arr.map((e, i) => ((i+1) % 2 === 0) ? e + n : e)
	: arr.map((e, i) => ((i+1) % 2 !== 0) ? e + n : e);

정말 지저분하고 복잡해 보이는 필자의 코드이다.

문제의 요구사항을 정리해보겠다.

배열의 길이가 홀수 + 순회하고 있는 배열의 인덱스가 짝수 (!홀수)
--> 해당 요소에 매개변수 n을 더한다.

배열의 길이가 짝수 + 순회하고 있는 배열의 인덱스가 홀수 (!짝수)
--> 해당 요소에 매개변수 n을 더한다.

이걸 적용해서 새로운 배열을 리턴.

이걸 XOR 연산자를 활용하면 정말 쉽게 문제를 해결할 수 있었다.

const solution = (arr, n) => arr.map((e, i) => (arr.length % 2 === 0 ^ i % 2 === 0) ? e += n : e);

약간의 설명을 덧붙여보자면,

[2, 4, 5, 6, 7] 의 배열을 arr 에 인자로 전달한다고 가정해보자.

  • map 을 통해 2를 시작으로 배열을 순회할 것이다.
  • arr.length = 5 이므로 arr.length % 2 === 0 는 false.
  • i (index) 는 0 이므로 i % 2 === 0 는 true.
  • false ^ true 는 true 이므로, 삼항 연산자를 통해 2 에는 e += n 을 적용
  • 다음 요소들도 같은 방식으로 진행

추후에 XOR 을 활용할 수 있는 문제가 또 나왔으면 좋겠다.

4. for...in vs for...of

4-1 for...in

for (variable in object)
  statement

for...in 문은 객체의 프로퍼티를 순회할 때 주로 사용된다.

const object = { a: 1, b: 2, c: 3 };

for (const property in object) {
  console.log(`${property}: ${object[property]}`);
}

// Expected output:
// "a: 1"
// "b: 2"
// "c: 3"

다음과 같이 프로퍼티의 key 를 variable 매개변수로 전달하여, 객체의 프로퍼티에 접근할 수 있다.

배열도 객체이기 때문에 for...in 을 활용할 수 있으며, 이때 배열의 각 요소를 프로퍼티로 인식하여 key 는 요소의 index, value 는 해당 요소의 값으로 평가된다.

const arr = [1, 2, 3]

for (const n in arr) {
	console.log(`${n}: ${arr[n]}`);
}

// "0: 1"
// "1: 2"
// "2: 3"

자바스크립트 Deep Dive 에 따르면, for...in 문으로 배열을 순회할 경우, 배열도 객체이므로 상속받은 프로퍼티가 포함될 수도 있다고 하여 일반적인 for 문, for...of 혹은 forEach 를 사용하기를 권장하고 있다.

4-2 for...of

for (variable of iterable)
  statement

for...of 문은 배열을 순회할 때 주로 사용된다.

const array1 = ['a', 'b', 'c'];

for (const element of array1) {
  console.log(element);
}

// Expected output: "a"
// Expected output: "b"
// Expected output: "c"

매개변수 variable 에는 변수를 선언하여 그 변수를 통해 배열의 요소에 접근할 수 있다.

5. Math 메소드 모음

5-1. Math.max()

Math.max()
Math.max(value0)
Math.max(value0, value1)
Math.max(value0, value1, /* … ,*/ valueN)

매개변수에 원하는 만큼의 숫자값을 전달하여 인자로 전달된 값들 중 가장 큰 값을 리턴하는 메소드이다.

console.log(Math.max(9, 3, 2));
// Expected output: 9

console.log(Math.max(-1, 8, -2));
// Expected output: 8

const array1 = [1, 3, 2];

console.log(Math.max(...array1));
// Expected output: 3

위와 같이 스프레드 연산자를 사용하여 배열을 분해하여 max 메소드를 적용할 수도 있다.

5-2. Math.sqrt()

Math.sqrt(x)

매개변수 x 에 전달된 인자의 제곱근을 반환하는 메소드다.

Math.sqrt(9); // 3
Math.sqrt(2); // 1.4142135623730951

Math.sqrt(9) === 9 ** 1/2

숫자타입의 값에 직접 1/2 를 제곱한 값과 일치 비교를 하면 false 가 나온다.

0.1 + 0.2 === 0.3 이 false 인 것과 비슷한 맥락으로, 이는 추후에 자세히 포스팅 하도록 하겠다.

정확한 제곱근 값을 리턴하려면 sqrt 메소드를 사용하도록 하자.

profile
병아리 개발자

0개의 댓글