[Achievement Goal]
1. 원시자료형(primitive type) vs 참조자료형(reference type)의 차이 알기
2. 스코프의 의미와 왜 적용하는지 이해하기.
- 전역 스코프 ,지역 스코프
- 전역 변수, 지역 변수간의 우선순위
- 중첩규칙, block 스코프, 함수 스코프
3. let/ const / var 의 차이.
하지만 변수(let,var)에 저장된 정보는 다시 재할당 하여 내용을 변경할 수 있다.
(상수 const 는 재할당 불가)
let num = 3
num = 5 // let 은 재할당 가능
const word = 'coding is very difficult '
word = 'coding is very fun' // const 는 재할당 불가.
// 각각의 주머니에 담긴 데이터는 여러 메소드를 통하여 데이터값 변동 가능.
const participant = ['sally','sook','bob','carry','tom']
const person ={
name : 'sally',
age : 30,
city : 'vancouver'
}
🤔 헷갈리기 쉬운 reference type .
'배고파' === '배고파' // true => 원시타입
['배고파','밥줘'] === ['배고파','밥줘'] // false => 참조,주소타입
둘다 눈으로 보기엔 같은값을 할당해 주고 있는것 같은데
결과는 true / false 로 다르다.
그 이유는 원시타입은 변수 하나에 정적인 데이터 값 하나만 들어가기 때문에
눈으로 보이는 값이 같다면 true 가 될 수 있다.
하지만 참조타입은 데이터가 담긴 주머니/주소 의 개념이다.
heap 이라는 공간안에 각 주머니를 차지하고 있기 때문에 같아질 수 없다.
[] !== [] 빈 배열또한 같아질 수 없는 이유와 같다.
레퍼런스타입 + 레퍼런스 타입 끼리 뭉치면 서로 영향을 받고,
레퍼런스타입 + 원시타입 끼리 뭉치면 원시타입은 레퍼런스 타입에 영향을 끼치지 않는다!
아 .. 알겠다 .. !
예시 👇🏼
let num = 30; <!--바깥 스코프-->
if(num){
let name = 'sook' <!-- 내부 스코프 -->
let introduce =`hello, i'm ${name} of ${num}'s $`
console.log(introduce) // `hello, i'm sook of 30's $`
}
console.log(introduce) <!-- reference error!-->
이렇게, 바깥 스코프에 있던 num = 30 변수는 if 문 안에 있는 introduce 변수에 반영되어 콘솔로그에 찍히지만,
바깥에 있는 콘솔로그의 introduce 변수는 내부 스코프의 introduce 변수에 영향을 받을 수 없어 레퍼런스 에러가 나게 된다.
🤔 헷갈리기 쉬운 scope .
전역 변수는 지역 변수에 영향을 끼치지만 그 반대는 불가하기 때문에, 지역 스코프로 갈 수록 사용 가능한 범위가 넓어진다. (지역 스코프의 우선순위가 더 높다.)
즉, 지역 스코프에서 전역 스코프로 접근할 수 있으며 그 반대는 불가하다.
블록 스코프는 중괄호를 기준으로 구분하는 범위를 뜻하며,
함수 스코프는 함수(function) 키워드안에 들어있는는 함수 선언식 및 표현식의 범위를 뜻한다.
예외적으로, 함수 실행문 중 화살표 함수 ()=>{} 는 블록 스코프에 해당된다.
블록 스코프의 예시 👇🏼
let name = 'sook'
if(name) {
let age = '30'
console.log(my name is ${name} of ${age}
}
함수 스코프의 예시 👇🏼
let name = 'sook'
function name(){
let age = '30'
console.log(my name is ${name} of ${age}
}
let 과 const 가 나오기 전, 개발자들은 변수 var 를 사용해왔다.
그렇다면 정확하게 var 는 어떤 변수일까?
앞서, 블록/함수 스코프를 기준으로 지역변수는 전역변수에 영향을 끼치지 못한다고 설명하였다. 하지만 블록스코프에서 var 를 쓰면 이를 무시하고 가장 최신에 썼던 변수명이 최종 리턴되어진다. (함수 스코프는 let과 동일.)
예시👇🏼
for(var i = 0; i < 5; i++){
console.log(i) // 1,2,3,4,5
}
console.log(i) // 5
let 대신 var 를 썼더니 전역스코프에서 실행시켜도 블록스코프를 무시한 채 결과값 5가 출력되었다.
이러한 방식은 지역스코프 바깥을 벗어나도 실행이 되기 때문에 코드가 많이 들어가는 하나의 프로젝트를 진행 할 때 오류를 발생시키기 쉽다.
그리고 그럴일은 드물겠지만 let 키워드는 var 키워드와 다르게 재 선언을 방지하는 기능이 있다. 그렇기 때문에 안전성의 이유로 var 대신 let 키워드를 쓰는것을 추천한다.
const 는 변수가 아닌, 상수이다.
이말은, 변하지 않는 값을 말하며 한번 할당 시 재할당이 불가하다.
그럼에도 쓰는 이유는, 값의 변경을 최소화 하여 안전한 프로그램을 만들 수 있기 때문에 값이 재할당 될 일이 없다면 const 사용이 권장 된다.
const div = document.queryselector('div')
const section () => { ~~ }
let이든 const 든, 변수명은 명확하게 명확하게 입력해주도록 한다.
만약 변수명을 작성하지 않는다면 작동은 하겠지만 모든 것을 var 로 받아들여
원치않은 결과를 초래 할 수 있다.
혹시모를 사태를 방지하고 싶다면 'use strict' 를 먼저 선언한 후 코딩을 시작해도 좋다.
name = 'sook' // var = 'sook' 으로 인식
🤔 헷갈리기 쉬운 const .
const p = document.queryselector('p')
p.textContent = 'hi'
p 는 const 로 선언해서 재할당이 불가한것으로 알고있는데 어떻게 hi 가 될까?
엄밀히 말하면 p는 재할당 된것이 없다.
p의 textContent 가 'hi' 로 재할당 된 것일뿐!