[TIL]데브코스 프론트엔드 0905

hyojeong·2021년 9월 5일
0

데브코스

목록 보기
27/50
post-thumbnail

📚TIL

day11

var, let, const

  • var : function scope, 변수 재할당 가능
  • let : block scope, 변수 재할당 가능
  • const : block scope, 변수 재할당 불가능
  • let,const 는 block scope이며 if, for, while 등의 block구문 단위로 범위를 가짐
  • 호이스팅(hoisting) : var로 선언된 변수, 함수는 호이스팅이 일어나 코드 실행시 var가 선언된 맨 위로 모든 var로 된 키워드가 올라가는 현상 발생
  • 호이스팅에 의해 var로 선언된 변수는 함수 선언부 위로 끌어올려지기 때문에 값 할당 전에 호출될 수 있음 - undefined 출력
  • let, const의 경우에도 호이스팅이 일어나지만 Temporary Dead Zone이라는 개념 덕분에 할당되기 전에 호출시 에러 발생

new 생성자

  • javascript는 함수를 실행할 시 new 키워드를 통해서 실행
function Cat(name, age){
	this.name = name
	this.age = age
}

const blackCat = Cat('kiki', 3)	
console.log(blackCat.name)	
// new를 사용하지 않고 실행시 this가 윈도우를 가리키게 됨
// return 값이 없기 때문에 undefined가 반환되고 undefined.name이 되어 에러 발생

console.log(window.name)	// kiki
// 의도치 않게 전역 윈도우 객체를 오염시킴
// const blackCat = new Cat('kiki', 3)
  • new 키워드를 붙이면 Cat 함수 내의 this는 윈도우가 아닌 new를 통해 실행된 Cat 함수의 새로운 객체를 가르킴
  • new 키워드를 붙일 시 따로 return문을 사용하지 않아도 this에 blackCat이 들어가게 됨
  • 이런 특징을 사용해 객체지향 문법을 흉내낼 수 있음

function Scope

  • javascript는 변수나 함수를 선언할 때 해당 변수와 함수의 선언을 감싸고 있는 function에 묶임
  • 만약 별다른 function으로 묶지 않고 변수랑 함수를 선언하여 script src로 끌어쓸 경우 윈도우 객ㄱ체에 모든 선언들이 묶이는 상태가 됨 - 전역이 계속해서 오염되어 여러 문제 발생 가능
  • 변수나 함수가 function에 묶인다는 특성을 사용하여 함수로 한번 감싸고 변수나 함수를 선언한다면 window를 침범하지 않고 사용 가능

this

  • javascript의 this는 일정하지 않고 함수가 실행되는 시점에 실행되는 경우가 대부분
  • 다른 함수를 이용해 this 고정이 가능함
  • this 특징으로 발생하는 문제 예시
const film = {
	title : 'her',
  	genre : 'drama',
  	actors : {
    	JoaquinPhoenix : {
          actorName : 'Joaquin Phoenix',
          introduction : function() {
          	console.log(`films : ${this.title},
		main character : ${this.actorName}`)
          }
        }
    }
}

films.actors.JoaquinPhoenix.introduction()
//movie : undefined, main character : Joaquin Phoenix
//introduction 함수 내에서 불러온 this가 JoaquinPhoenix객체를
//나타내기 때문에 이 객체 내부엔 title이 없어 undefined가 출력
  • 문제 해결 방법 : this.title을 movies.title로 변경하여 직접 참조함

function Scope & this

  • javascript는 function scope 사용에 따라 this가 달라진다는 점에 유의해야함
function HorrorMovie(actors){
	this.actors = actors
	this.role = function(){
    	setTimeout(function() {
        	this.actors.forEach(function(actor){
            	// 여기에 쓰인 this는 HorrorMovie의 this가 아닌
          	// setTimeout의 this를 가르키기 때문에 actors가 존재하지 않음
              	actor.role()
            })
        })
    }
}

var DawnOfTheDead = new HorrorMovie([
  {
  	name : 'Sarah Polley',
    role : function(){
    	console.log('Lead : Sarah Polley')
    }
  }
])

DawnOfTheDead.role()
  • arrow function을 통한 해결 : arrow function은 scope를 갖지 않기 때문에 해당 arrow function의 상위에 있는 funciton scope를 찾아가게 되어 HorrorMovie의 this를 불러올 수 있음
  • bind를 통한 해결 : function으로 선언된 함수 끝에 .bind(this)를 추가하면 함수 내 this를 특정한 this로 변경된 함수로 만들어줌기 때문에 .bind(this)의 this는 this.role의 this가 됨
  • clouser를 통한 해결 : HorrorMovie의 this를 변수에 저장하여 내부함수에서 참조하여 사용함, 내부의 function에서 외부의 변수를 참고하는 것을 clouser라고 함

clouser

  • 내부 함수에서 외부 함수의 변수에 접근할 수 있음
  • clouser는 함수와 함수가 선언된 어휘적 환경의 조합이라고도 함
  • clouser 사용 시 발생할 수 있는 문제 예시
const numbers = [0, 1, 2, 3]

for(var i = 0; i < numbers.length; i++){
	setTimeout(function(){
      //여기서 사용된 i는 function 외부에서 선언된 변수
      //따라서 setTimeout이 실행된 시점에 i는 이미 for 루프가 다 끝나 4인 상태
      //numbers[4]는 존재하지 않기 때문에 undefined 반환
    	console.log(`numbers[${i}] : ${numbers[i]}`)
    }, 1000)
}
//[4] : undefined
//[4] : undefined
//[4] : undefined
//[4] : undefined
  • IIFE를 통한 해결 : function scope로 가두면 i의 값에 따라 각각의 함수들이 생기기 때문에 for루프가 끝나더라도 각각의 i가 들어간 함수 출력이 가능
  • let을 통한 해결 : let,const는 function scope가 아닌 block scope이기 때문에 for루프 안에서만 유효한 변수, 따라서 let으로 선언할 경우 setTimeout 내에서 i에 따라 각각 참조됨
  • forEach를 통한 해결 : forEach는 배열을 순회하면서 각각의 function을 만들기 때문에 i의 값이 고유하게 실행됨

clouser를 이용한 private 효과

  • clouser를 이용한 트릭 중 하나로 private 효과가 있음
  • 이 특징을 이용하여 외부에 노출하면 안되는 값을 보호할 수 있음
  • 보호해야 하는 값을 함수 내부에서만 바꿔서 조작하는 함수를 return하는 식으로 사용
function Counter(){
	let count = 0
    
    function increase(){
    	count++
    }
  	function printCount(){
    	console.log(`count : ${count}`)
    }
  	
  	return {
    	increase,
      	printCount
    }
}

const counter = Counter()
//Counter에서 return하는 increase, printCount가 들어간 객체가 들어있음

counter.increase()
counter.increase()
counter.increase()
counter.increase()
counter.printCount()	//count : 4

console.log(counter.count)	//undefined
// 외부에서는 Counter 내의 count에 접근 불가
// counter에는 두가지 함수만 return될 뿐 count는 없기 때문에
// 실제로 counter에 count가 들어있지 않음 

🌊하루를 마치며

프로젝트가 끝나고 우선적으로 밀린 강의를 들었다! 클로저와 스코프에 대한 내용이 주를 이뤘는데 1주차 강의 때 배웠던 부분이지만 가볍게 넘어갔던 부분이었다. 완벽히 이해가 가지 않아 아티클로 따로 정리하려 했는데 매 주가 고비였기 때문에 어영부영 넘어갔었던 기억이 난다. 이번 강의를 통해서 공부하고 싶었던 부분을 정확하게 공부할 수 있어서 좋았다. 처음엔 코드를 짤 때 전역 변수를 설정하고 함수 내부에서 이 변수를 사용하는 것을 당연하게 생각했기 때문에 스코프와 클로저 개념이 따로 존재한다는 것이 새로웠다. 공부하면서 내가 알던 개념적 부분 외에도 이 기능을 프라이빗한 정보를 다루는데도 사용할 수 있다는 점이 흥미로웠다. 클로저에 대한 내용은 잘 이해됐지만 강사님께서 클로저에 대한 이해도에 따라 코드의 퀄리티가 달라진다고 말씀하셔서 더 깊게 공부해놓으면 좋을 것 같다고 판단돼 아티클도 작성할 생각이다!
내일이면 6주차가 시작되는데 이번주는 강의가 밀리지 않아서 더 깊게 공부하고 싶은 부분들이나 프로젝트를 수정할 수 있는 시간을 가질 수 있었으면 좋겠다!

profile
Front-end Develop🥰

0개의 댓글