TIL 2)Javascript Koans

Hover·2023년 3월 6일
0

TIL

목록 보기
3/27

시작하기

이번 코드스테이츠 과제는 javascript 문법에 대해 돌아보는 시간을 가지는 과제였다.

이런 식으로 js파일에 정답을 입력하면 html 위에 정답과 오답을 확인할 수 있게 되었다.
총 10가지 part로 나뉘어져 있으며, 문제 하나하나는 간단하지만, 깊은 고민을 요구하는 문제도 있다.

Koans 문제를 다시 되돌아보는 겸 정리를 하며 충분히 내 것으로 만들기 위해 이 글을 작성하였다.

01. let & const

const는 상수로써 재할당이 금지된다.

const a = "hello";
a = "bye";
console.log(a); // TypeError:Assignment to constant variable.

반면, const로 선언된 배열 또는 객체는 속성을 추가하거나 삭제 할 수 있다.

const arr = [1, 2, 3, 4, 5];
const obj = {
  name: "hi",
  age: 20,
};

arr.push(6);
obj.school = "incheon";

console.log(arr); // [ 1, 2, 3, 4, 5, 6 ]
console.log(obj); // { name: 'hi', age: 20, school: 'incheon' }

객체 타입(배열 등)이 const로 선언했음에도 불구하고 수정이 되는 이유는 const로 선언된 상수는 참조를 못할 뿐이지 그 상수가 참조하는 원본 프로퍼티는 수정하지 못하는 것이다.

  • 물론 직접 할당은 불가능하다 ex) arr=[6,7,8]

참고블로그 : https://velog.io/@hyoniii_log/JavaScript-const-%ED%82%A4%EC%9B%8C%EB%93%9C

let은 재할당이 가능하다. 하지만, var 역시 재할당이 가능한데 왜 let만 쓰는걸까??

  • 중복 허용

var은 중복을 허용하지만 , let과 const는 중복을 허용하지 않는다.

var x = 1;
var x = 2; //no error

let x = 1
let x = 2; // error

const x = 1;
const x = 2; //error

만약 전역변수를 var로 선언하고 여러 곳에 할당하였는데 어느 부분에서 전역변수와 똑같은 이름의 변수를 선언해버리면 큰 문제가 일어날 수 있다.




  • 호이스팅

var 키워드로 선언된 변수는 선언문 이전에 참조가 가능하다.

하지만, let과 const는 선언문 이전에 참조할 수 없다.

console.log(x); //undefined
var x = 1;

console.log(y); //error
let y = 1;

console.log(z); //error
const z = 1;

첫번째 코드를 보면 선언&초기화 이전에 참조를 했는데도 reference error가 아닌 undefined가 출력된다.(에러가 없단 소리)
이 현상을 호이스팅이라 하는데 호이스팅은 코드의 가독성과 유지보수를 위해서라도 지향해야 한다.





02.scope

scope란 유효 범위란 뜻으로 스코프 내의 변수 또는 함수는 그 스코프 안에서만 참조가 가능하고, 외부로 나갈수 없는 특징을 가졌다.

let global = "global";

function inner() {
  const local = "local";
  global = "newglobal";
}
inner();
console.log(global); // newglobal
console.log(local); // error

local은 inner 함수 내 스코프에 있어서 외부에서 참조가 불가능하다.
반면 global은 전역 스코프라 어디서든 사용할 수 있다.

클로저는 여기에다가 정리 했음!
https://velog.io/@liso_o/TIL-1-%ED%81%B4%EB%A1%9C%EC%A0%80




03.ArrowFunction

화살표 함수는 함수 표현식을 보다 간단하게 만든 문법이다

let fuc = function(a,b){
    return a+b;
}

let func = (a,b)=>{
    return a+b;
}

04.원시 자료형&참조 자료형

Javascript에서 자료형은 값의 종류다

console.log(typeof "hello");  // string
console.log(typeof true); // boolean
console.log(typeof 20); // number
console.log(typeof undefined); // undefined

또한 여기에는 배열과 객체도 포함이 된다

위 자료형들은 원시 자료형/참조 자료형 으로 나눌 수 있다.

원시 자료형 중 가장 많이 사용되는 것은

string , number , boolean , undefined , null

자바스크립트에서 원시 자료형이 아닌 모든 것들은 참조 자료형이다.(배열 / 객체 )

1. 저장

원시 자료형은 값 자체를 저장한다.

let a = 10;

변수 a를 선언하면 메모리에 a라는 이름을 가진 공간을 확보하고 거기에 할당된 값 10을 넣는다.

반면에 참조 자료형은 원시 자료형처럼 값을 저장하지 않는다.

참조 자료형을 변수에 할당할 때는 변수에 값이 아닌 주소를 저장한다.

let a = [1,2,3,4,5];

위와 같은 경우에 1,2,3,4,5 라는 값은 다른 곳에 저장이되고, a라는 변수에는 1,2,3,4,5가 저장되어 있는 주소를 할당한다.

이로인해 참조 자료형은 동적으로 크기가 변하는 데이터를 보관할 수 있다.

2.복사

let a = 10;
let b = a;

원시 자료형을 위와 같이 다른 변수에 할당하면 값이 복사된다.

let arr1 = [0,1,2,3,4,5]
let arr2 = arr1

참조 자료형이 할당된 변수를 다른 변수에 할당하면 해당 변수의 주소가 복사된다.

따라서 위 두 변수는 같은 주소를 가르킨다.

같은 주소를 가르키므로 원본을 변경하면 자연스럽게 복사본도 변경이된다.

let arr1 = [1, 2, 3, 4, 5];
let arr2 = arr1;
console.log(arr2); // [1,2,3,4,5]
arr1.push(6);
console.log(arr2); // [1,2,3,4,5,6]

반대로 복사본을 변경을 해도 같은 주소를 가르키고 있기 때문에, 원본도 값이 변경 된다.

let arr1 = [1, 2, 3, 4, 5];
let arr2 = arr1;
arr2.push(6);
console.log(arr1);

3. 변경 불가능한 값vs변경이 가능한 값

한번 생성된 원시 값은 변경할 수 없다.

let a = 10; 
a=20;

// 두 개의 메모리 주소값 다름.

a에 20을 할당한 순간에 새로운 메모리 주소에 a와 20이 저장된다.

그리고 기존에 있던 값은 자동으로 메모리에서 삭제한다 (가비지 콜렉터)

반면에 참조 자료형은 주소를 받고 있으니 기존 값의 값만 수정해주면 되기 때문에, 메모리 주소가 변하지는 않는다.

4. 얕은 복사

위와 같이 참조 자료형은 주소를 복사하기 때문에 원본에 영향을 미친다.

참조 자료형 중 하나인 배열을 복사하는 방법에는 여러가지가 있다.

1. slice()
let arr1 = [0,1,2,3];
let arr2 = arr.slice();
arr2.push(4);
console.log(arr1); // [ 0, 1, 2, 3 ]
console.log(arr2); // [ 0, 1, 2, 3, 4 ]

2. spread
let arr1 = [0,1,2,3];
let arr2 = [...arr1];
console.log(arr1===arr2); // false, 그러나 값은 같음.

객체 역시 참조 자료형이라 복사하는 방법이 있다.

1. Object.assign()
let obj1 = { firstName: "coding", lastName: "kim" };
let obj2 = Object.assign({}, obj);

console.log(obj2) // { firstName: "coding", lastName: "kim" }
console.log(obj2 === obj1) // false

2. spread
let obj1 = { firstName: "coding", lastName: "kim" };
let obj2 = {...obj1};
profile
프론트엔드 개발자 지망생입니다

0개의 댓글