Skip to content

Latest commit

 

History

History
executable file
·
393 lines (325 loc) · 6.65 KB

2. variables.md

File metadata and controls

executable file
·
393 lines (325 loc) · 6.65 KB

2. Variables - let, const

2-1. let

2-1-1. 소개

let a = 1
function f () {
  console.log(a, b, c)
	let b = 2
	console.log(a, b, c)
	if (true) {
		let c = 3
		console.log(a, b, c)
	}
	console.log(a, b, c)
}
f()
for (let i = 0; i < 5; i++) {
  console.log(i)
}
console.log(i)

2-1-2. let 상세

1) 재할당 가능

let a = 1
a = 2
console.log(a)

2) 반복문 내에서의 함수 실행시

var funcs = []
for (var i = 0; i < 10; i++) {
  funcs.push(function () {
    console.log(i)
  })
}
funcs.forEach(function (f) {
  f()
})
var funcs = []
for (var i = 0; i < 10; i++) {
  funcs.push((function (v) {
    return function () {
      console.log(v)
    }
  })(i))
}
funcs.forEach(function (f) {
  f()
})
let funcs = []
for (let i = 0; i < 10; i++) {
  funcs.push(function () {
	  console.log(i)
  })
}
funcs.forEach(function (f) {
  f()
})

for 문은 내부적으로 어떤 모습일까?

  • for문에서 i 값이 변경되는 매 루프마다 각각 새로운 블록스코프가 형성됨

  • 즉 아래와 같은 내용이 반복되는 형태로 생각하면 됨.

for (let i = 0; i < 10; i++) {
  funcs.push(function() {
    console.log(i)
  })
}
// ==================

{
  let i = 0;
  funcs.push(function(){ console.log(i); });
}

{
  let i = 1;
  funcs.push(function(){ console.log(i); });
}

{
  let i = 2;
  funcs.push(function(){ console.log(i); });
}
  • i 값이 for문 종료 이후에도 for문의 scope의 영향을 받는 경우와 같은 개념은 실행컨텍스트와 클로저에 대한 내용
  • 메모리 측면에서 효율적이라는 내용은 아래의 코드(ES5 하에서의 코드)와 비교하면 그렇다는 것입니다.
for (var i = 0; i < 10; i++) {
  (function (i) {
    funcs.push(function(){ console.log(i); });
  })(i);
}
  • 이 경우 i를 전달하기 위해 매번 즉시실행함수를 한 번 더 감싸기 때문에 상대적으로 성능이 저하될 수밖에 없음

2-2. const

2-2-1. const 상세

1) 재할당

  • 불가, 재할당시 오류가 발생
const PI = 3.141593
PI = 3.14

2) 최초 선언시 할당하지 않으면

  • 에러가 발생한다.
const PI
PI = 3.14

3) 참조타입 데이터의 경우

  • 참조타입의 경우 내부 값이 변경이 가능하다.
  • 구체적으로 OBJ 내부의 property는 변경이 가능하다.
  • 참조타입 자체는 mutable 하기 때문이다.
const OBJ = {
  prop1 : 1,
  prop2 : 2
}
OBJ.prop1 = 3
console.log(OBJ.prop1)
  • 배열도 근본적으로는 객체이게 때문에 동일한 로직이 적용된다.
const ARR = [0, 1, 2]
ARR.push(3)
delete ARR[1]
console.log(ARR)
  • 만약에 참조값 내부도 immutable 하게 하고 싶다면?

해결방안: Object.freeze(), Object.defineProperty()

const OBJ = {}
Object.defineProperty(OBJ, 'prop1', {
  value : 1,
  writable: false, // 재할당 금지 옵션 
  configurable: false //
})

const OBJ2 = {
  prop1 : 1
}
Object.freeze(OBJ2)

여전히 남는 문제점: nested Object의 경우...

const OBJ = {
  prop1 : 1,
  prop2 : [2, 3, 4],
  prop3 : { a: 1, b: 2 }
}
Object.freeze(OBJ)
OBJ.prop1 = 3
OBJ.prop2.push(5)
OBJ.prop3.b = 3
console.log(OBJ)

Object.freeze(OBJ.prop2)
OBJ.prop2.push(6)
console.log(OBJ)
  • 내부 객체까지 재귀적으로 freeze 하는 키워드 - deepfreeze
  • deepcopy 키워드도 함께 알아두자.
  • immutable 한 객체라는 키워드(데이터 기반의 자료형 다뤄야하는 환경에서 중요한 키워드)

4) 반복문 내부에서의 상수

var obj = {
  prop1: 1,
  prop2: 2,
  prop3: 3
}
// (추가) for in 문에 const 를 쓰는 이유라도 ? 
// for 문이 실행되는 과정에서 내부적으로 프로퍼티를 변경못하게 하기 위해
// 안될 것 같지만 된다.
for (const prop in obj) {
  console.log(prop)
}
// 위 코드는 사실 아래와 같은 코드여서 에러가 발생하지 않는다.
let keys = Object.keys(obj);
for(let i = 0; i <keys.length; i++){
  const prop = obj[keys[i]];
  console.log(prop);
}

{
  const prop = obj[key[i]];
  console.log(prop);
}
{
  const prop = obj[key[i]];
  console.log(prop);
}
{
  const prop = obj[key[i]];
  console.log(prop);
}
{
  const prop = obj[key[i]];
  console.log(prop);
}
...


// 이 코드도 에러를 발생하지 않는다.
for (const element of obj) {..}



// 이 코드는 에러가 발생한다. 
for (const i = 0; i < 5; i++) {
  console.log(i)
}
{
  const i = 0;
  console.log(i);
}
{
  const i = 0;
  console.log(i);
}

// 아직 의문점이 남는다. 아래 for 문에서도 각 i 는 독립적인 block scope를 가지게 되는 것이 아닌가?
// 현재 강의에 질문을 남겼다. 
  • 위 코드는 사실 아래와 같은 코드이기 때문에 된다.

2-3. 공통사항

1) 유효범위

{
  let a = 10
  {
    const b = 20
    console.log(b)
  }
  console.log(a)
  console.log(b)
}
console.log(a)

2) 재선언 (재정의)

var a = 0
var a = 1
console.log(a)

let b = 2
let b = 3
console.log(b)

const c = 4
const c = 5
console.log(c)

var d = 4
let d = 5
const d = 6
console.log(d)

3) 초기화되기 전 호출

{
  console.log(a)
  let a = 10
  {
    console.log(b)
    let b = 20
  }
}

{
  console.log(a)
  const a = 10
  {
    console.log(b)
    const b = 20
  }
}

=> hoisting X ?

3) TDZ (Temporal Dead Zone, 임시사각지대)

{
  let a = 10
  {
    console.log(a)
    let a = 20
  }
}
{
  const a = 10
  console.log(a)
  {
    console.log(a)
    const a = 20
    console.log(a)
  }
}

4) 전역객체의 프로퍼티?

// 전역공간에서 var 로 선언한 변수는 전역변수임과 동시에 전역객체의 property

// 전역 객체의 프로퍼티 할당
window.b =10
// 지우기 가능 
delete window.b // ture

//어떻게 해도 지워지지 않음/ 양쪽에 다 걸려있어서 그럼
var b = 10 
delete window.b // false 
delete b // false 
b // 10 
window.b //10

var a = 10
console.log(window.a) // 10
console.log(a) // 10
delete a
console.log(window.a) // 10
console.log(a) // 10

delete window.a // false

window.b = 20
console.log(window.b)
console.log(b)
delete b
console.log(window.b)
console.log(b)

let c = 30
console.log(window.c) //전역 객체의 property와 전역 변수가 분리됨 
console.log(c) // 전역 변수에 해당
delete c //fale  delete 명령 자체가 객체의 프로퍼티를 지우라는 명령이기 때문에 안먹음 변수접근 x

l