그저 내가 되었고

항해99) 2주차:: 알고리즘 테스트 연습; Study more(1~14) 본문

개발/항해99 9기

항해99) 2주차:: 알고리즘 테스트 연습; Study more(1~14)

hyuunii 2022. 9. 25. 10:46

🎈 Study more

Variables; var vs let vs const

var: 중복 선언 가능

- 얘로 선언한 변수는 동일한 이름으로 여러번 중복해서 선언이 가능함. 마지막에 할당된 값이 변수에 저장될 뿐. 아래의 예제를 보면 에러 없이 각기 다른 값이 출력되는 것을 볼 수 있음.

- 이는 필요할 때마다 변수를 유연하게 사용할 수 있다는 장점이 될 수도 있지만, 기존에 선언해둔 변수의 존재를 잊고 값을 재할당하는 등의 실수가 발생할 가능성이 큼. 특히 코드량이 많아졌을 때, 같은 이름의 변수명이 여러 번 선언되었다면 어디 부분에서 문제가 발생하는지 파악하기 힘들뿐더러 값이 바뀔 우려가 있음.

var name = 'javascript';
console.log(name); // javascript

var name = 'react';
console.log(name); // react

 

let: 중복 선언 불가능, 재할당 가능

var과 다르게 let은 해당 변수가 이미 선언되었다는 에러 메시지가 출력됨. 이처럼 중복 선언이 불가능함.

name = 'vue'와 같이 변수 선언 및 초기화 이후 반복해서 다른 값을 재할당 할 수는 있음.

let name = 'javascript';
console.log(name); // javascript

let name = 'react';
console.log(name);
// Uncaught SyntaxError: Identifier 'name' has already been declared

name = 'vue';
console.log(name); // vue

 

const: 중복 선언 불가능, 재할당 불가능

- const는 constant(상수)를 뜻하기 때문에 한 번만 선언이 가능하며 값을 바꿀 수도 없음. 하지만 아래의 예제와 같이 배열과 오브젝트의 값을 변경하는 것은 가능함.

const name = 'javascript';
console.log(name); // javascript

const name = 'react';
console.log(name);
// Uncaught SyntaxError: Identifier 'name' has already been declared

name = 'vue';
console.log(name);
// Uncaught TypeError: Assignment to constant variable


function func() {
	const list = ["A", "B", "C"]

    list = "D";
    console.log(list);
    // TypeError: Assignment to constant variable

    list.push("D");
    console.log(list); // ["A", "B", "C", "D"]
}

- 결과적으로 const는 불변을 의미하는 것과 다르게, 값을 재할당하는 코드만 불가능하다고 볼 수 있음

 

 

 

+ 이어지는 개념인 스코프, 호이스팅

스코프(Scope): 유효한 참조 범위. var 변수의 스코프와 let 또는 const로 선언한 변수의 스코프가 다르다.

- var : 함수 레벨 스코프 (function-level scope); 함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없음. 즉, 함수 내부에서 선언한 변수는 지역 변수이고 함수 외부에서 선언한 변수는 모두 전역 변수로 취급됨.

function func() {
	if (true) {
    	var a = 5;
        console.log(a); // 5
    }
    console.log(a); // 5
}

func(); // 5
console.log(a); // ReferenceError: a is not defined

 

- let, const : 블록 레벨 스코프 (block-level scope); 함수, if문, for문, while문, try/catch문 등의 모든 코드 블록 ({...}) 내부에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없음. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수로 취급됨.

function func() {
	if (true) {
    	let a = 5;
        console.log(a); // 5
    }
    console.log(a); // ReferenceError: a is not defined
}

console.log(a); // ReferenceError: a is not defined

 

 

호이스팅(Hoisting): 함수 내부에 있는 선언들을 모두 끌어올려 해당 함수 유효 범위의 최상단에 선언하는 것(실제로 코드가 끌어올려지는 것이 아닌, 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는 과정에서 내부적으로 끌어올려 처리하는 것을 뜻하며 실제 메모리에서는 변화가 없음) → 미리 선언문을 실행해둔다고 이해하면 됨.

- var, 함수선언문: 호이스팅 발생; 아래 보면 변수 a 가 선언되기 전에 참조되었음에도 에러가 발생하지 않음. 이는 코드 실행 전에 자바스크립트 내부에서 미리 변수를 선언하고 undefined로 초기화를 해두었기 때문임. 함수선언문 또한 동일하게 선언되기 전 호출됨에도 에러가 발생하지 않음.

/* 변수 호이스팅*/
console.log(a); // undefined

var a = 5;
console.log(a); // 5

/*함수 호이스팅*/
foo(); // foo

function foo() {
	console.log("foo");
}

 

- let, const, 함수표현식: 호이스팅이 발생하지만, 다른 방식으로 작동됨; 아래 보면 변수 a가 선언되기 전에 참조하니 에러가 발생함. 이는 호이스팅이 발생하지 않는 것이 아닌, 변수의 선언과 초기화 사이에 일시적으로 변수 값을 참조할 수 없는 구간인 TDZ(Temporal Dead Zone)에 빠졌기 때문에 보이는 현상임. 함수표현식을 사용하거나 let또는 const로 변수를 선언하는 경우, 자바스크립트 내부에서는 코드 실행 전 변수 선언만 해둘뿐 초기화는 코드 실행 과정에서 변수 선언문을 만났을 때 수행함. 그렇기 때문에 호이스팅이 발생하기는 하지만, 값을 참조할 수 없기 때문에 동작하지 않는 것처럼 보이는 것임.

/* 변수 호이스팅 */
console.log(a); // ReferenceError: a is not defined

let a = 5;
console.log(a); // 5

/* 함수 호이스팅 */
foo(); // error

var foo = function() {
	console.log("foo");
}

substring()

string 객체의 시작 인덱스로 부터 종료 인덱스 전 까지 문자열의 부분 문자열을 반환

const str = 'Mozilla';

console.log(str.substring(1, 3));
// expected output: "oz"

console.log(str.substring(2));
// expected output: "zilla"

 


consol.log( ) vs return

console.log( ): 이전에 정의된 모든 종류의 변수 또는 사용자에게 표시해야 하는 메시지를 인쇄하는데 사용되는 JS 함수

return: 함수 실행을 종료하고, 주어진 값을 함수 호출 지점으로 반환(결과값을 저장). 출력(호출)은 안하니까 찍어보려면 console.log( )로 해봐야됨.

그래서

function sayHi(name, city) {
	console.log(`Hi! ${name}, u live in ${city}?`);
    }
const greetLeeche = sayHi("Leeche", "NY")

console.log(greetLeeche)

얘👆🏻의 결과는 이런👇🏻데

>

Hi! Leeche, u live in NY?

undefined

>

WHY? 유기적으로 연결된 코드 속에서 console이 두 번 쓰여서 function 내부의 console만 제대로 찍힌 것. 이 때 return으로 결과값을 저장한게 아니므로 greetLeeche에 할당된 값이 없다며 undefined가 찍힌 것

 

function sayHi(name, city) {
	return(`Hi! ${name}, u live in ${city}?`);
    }
const greetLeeche = sayHi("Leeche", "NY")

console.log(greetLeeche)

얘👆🏻의 결과는 이럼👇🏻

>

Hi! Leeche, u live in NY?

>

WHY? 함수 마지막에 return으로 결과값을 저장했으므로 깔끔하게 greetLeeche에 할당된 값이 찍혀 나오는 것.


parseInt( )

: 문자열을 정수로 변환하는 함수

 

e.g.)

parseInt("10");  // 10

parseInt("-10");  // -10

parseInt("10.9");  // 10(실수값은 소수점 걍 제거 후-올림도 내림도 아님- 정수 부분만 리턴)

parseInt(10);  // 10(파라미터로 문자열이 아닌 다른 타입이 전달되면 걍 파라미터를 문자열로 변환하여 처리)

parseInt("k10");  // NaN(문자열의 첫글자가 숫자가 아니면 NaN 리턴)


charAt( )

: 인수번째의 문자를 읽어내는 메서드(지정된 인덱스의 문자를 돌려줌)

※ 주의) CS에서 자릿수(n번째)는 0부터 센다!!!!!!!

 

e.g.)

let str = "I Love Haikyuu-!!";

console.log(str.charAt());  //I
console.log(str.charAt(1));  // (공백. 왜?! 띄어쓰기도 한 문자 취급!!!!)
console.log(str.charAt(-1));  //!
console.log(str.charAt(str.length-1));  //!
console.log(str.charAt(str.length));  // (공백. 왜?! 휴,, 이게 좀 헷갈리는데. 밑에서 설명)

👆🏻마지막에 console.log(str.charAt(str.length)); 이건 공백이 나온다. 왜?!

console.log(str.length)를 찍으면 17이 나온다. 띄어쓰기를 포함해서 계산한다.

근데 charAt( )는 자릿수기에 0번째, 1번째... 이렇게 나감. 그러니 마지막 !는 16번째가 됨 ㄷㄷㄷ

 

 

indexOf(인수)

: 인수가 들어 있는 위치를 읽어냄(lastIndexOf는 뒤에서부터 셈)

e.g.) "javascript".indexOf("s")는 4

 

 

substring(인수, 인수)

: charAt은 문자하나를 읽어냈쥬? 얘는 문자열을 읽음

e.g.) "javascript".substring(1, 3)은 "ava"


Math.abs(__)

: Math.___( )에서 Math는 수학적인 상수와 함수를 위한 속성과 메서드를 가진 내장 객체. 

가장 많이 사용되는 목록은 아래와 같음.

1. Math.min(__, __, __, __ ...)

2. Math.max(__, __, __, __ ...)

3. Math.random(__, __, __, __ ...);  0보다 크거나 같고 1보다 작은 무작위 숫자(random number)를 반환

4. Math.round(__); 인수로 전달받은 값을 소수점 첫 번째 자리에서 반올림

5. Math.floor(__); 인수로 전달받은 값을 소수점 이하에서 내림(어떤 실수의 바닥의 수인 바로 아래 정수로 내림)

e.g.)

Math.floor(10.95);  // 10

Math.floor(11.01);  // 11

Math.floor(-10.95); // -11

Math.floor(-11.01); // -12

6. Math.ceil(__); 인수로 전달받은 값을 소수점 이하에서 올림(어떤 실수의 천장의 수인 바로 위 정수로 올림)

e.g.)

Math.ceil(10.95);  // 11

Math.ceil(11.01);  // 12

Math.ceil(11);     // 11

Math.ceil(-10.95); // -10

Math.ceil(-11.01); // -11

 

Math.abs(__)는 생김새만 봐도 알겠지만 인수의 절댓값 리턴.


const ___ = [ _, _, _, ....] (how to make an array exactly?)

JS에서 배열을 선언하는 방법?

1. let arr1 = [ ]; or let arr1 = ['bokuto', 'sakusa', 'kuroo'](배열의 길이: 3)

👉🏻대괄호를 이용하여 빈 배열을 생성할 수도 있고, 배열을 선언할 때 초기값을 넣어 줄 수도 있음.

👉🏻심지어 배열 안에 배열도 넣을 수 있음. const arr = ['kita', 1, true, ["kitasan", "iluvyu"]](배열의 길이: 4!!!!)

2. let arr2 = new Array();

👉🏻대괄호를 사용한 1번의 방법과 별 차이 없음. 근데 배열의 길이를 미리 줄 수 있는 것 같음.

e.g.) const arr = new Array(2); 라고 하면 arr.length 찍으면 2 나옴. 대신 값이 뭔지 선언한 게 없으니까 arr[0] 찍으면 아무것도 안나옴. 만약에 그냥 new Array( ); 만들면 length가 0인 배열을 생성.


___.filter(x => !numbers.includes(x));

: 두 배열의 비교 방법. 얘는 차집합(Difference)을 찾아줌(Array의 filter와 includes prototype Method 이용)

// 배열 선언
const arr1 = ['1','2','3','4','5'];
const arr2 = ['1','2'];

// 차집합(Difference)
console.log(arr1.filter(x => !arr2.includes(x)));


>
['3','4','5']
>

 

 + 교집합(Intersection)?

// 배열 선언
const arr1 = ['1','2','3','4','5'];
const arr2 = ['1','2'];

// 교집합(Intersection)
console.log(arr1.filter(x => arr2.includes(x)));


>
['1','2']
>

___.reduce((a, b) => a+b, 0);

: 배열의 빌트인 함수. 보통 배열의 요소들을 하나의 결과로 합치는 용도로 많이 씀. 나도 요소들의 합계를 구하는 용도로 썼었고. 배열의 빌트인 함수는 지금 잘 이해가 안됨. 차후 다시 공부 필요.

const arr1 = [ 1, 2, 3, 4, 5 ];
arr1.reduce((a, b) => a + b);  //15

 


sum += arr[i];

: 이게 뜻이 마음에 잘 안 와닿으...;;;

a += b? a = a+b 즉, 좌변의 수를 우변에 더한 후 좌변에 대입한다는 뜻.

function solution(arr) {
    let answer = 0;
    let sum = 0;
    
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i]
        
    }
    
    return answer = sum / arr.length;
}

👆🏻여기서.. for문 돌면서 배열의 요소들을 하나씩 더해서 누적 합계를 내준다는 것.

풀어 쓰면 sum = sum + arr[i]니까 처음 셋팅된 sum값인 0에 계속 누적해서 배열의 요소들의 값을 더해감.


_____.substring();

: string 객체의 시작 인덱스로 부터 종료 인덱스 전 까지 문자열의 부분 문자열을 반환

const str = 'MOCHARELLA';

console.log(str.substring(0, 3));
// expected output: "MOCH"

console.log(str.substring(2));
// expected output: "CHARELLA"

 

___.push(배열 이름);

: ___를 저 배열에 넣겠다

 

((👆🏻 둘👇🏻의 차이는 없어 보임!))

 

- 배열 이름.push(__);

: ___를 저 배열에 넣겠다

 

const animals = ['pigs', 'goats', 'sheep'];

const count = animals.push('cows');  //⭐
console.log(count);
// expected output: 4

console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows"]


animals.push('chickens', 'cats', 'dogs');  //⭐
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]

maybe.sort(function(a, b) {
   return a - b;

});  

: 배열을 오름차순 정렬하기

const maybe = [2, 1, 3, 10];

maybe.sort(function(a, b)  {
  return a - b;
});


>
[1, 2, 3, 10]
>

 

sort함수? 배열을 정렬하기 위해서 사용하는 함수. arr.sort([compareFunction]) 형태로 사용한다. 숫자는 물론 문자열도 정렬 가능.

const arr1 = [2, 1, 3];
const arr2 = ['banana', 'apple', 'orange']

arr1.sort();  //[1, 2, 3]
arr2.sort();  //['apple', 'banana', 'orange']

근데 문제가 생기는 지점이, sort에 파라미터를 주지 않으면 유니코드 순서에 따라 값을 정렬함.

1, 10, 2, 3을 넣으면 걍 고대로 나와버린단 뜻. 그러므로 파라미터를 함수로 줘서 해결해야 함.

 

const arr = [2, 1, 3, 10];

arr.sort(function(a, b)  {
  if(a > b) return 1;
  if(a === b) return 0;
  if(a < b) return -1;
});


>
[1, 2, 3, 10]
>

이걸👆🏻 이렇게👇🏻 단순화 하면 됨.

const arr = [2, 1, 3, 10];

arr.sort(function(a, b)  {
  return a - b;
});


>
[1, 2, 3, 10]
>

 

 

+ 내림차순 정렬하기?

const arr = [2, 1, 3, 10];

arr.sort(function(a, b)  {
  return b - a;
});


>
[10, 3, 2, 1]
>