본문 바로가기
[항해99] TIL

[항해99] 4일차(ES6, 일급 객체로서 함수, 실행 컨텍스트, 콜백 함수)

by @kkkk_biiin 2023. 8. 18.
728x90

ES6 문법 소개

1. 화살표 함수

function add() {}; // 함수 선언문
var add = function(){}; // 함수 표현식
var add = () => {}; // 화살표 함수
var add = () => 1; // return문이 한 줄일 때는 생력 가능
var add = x => 1; // 매개변수가 하나면 소괄호도 생략 가능

// 화살표 함수는 this를 바인딩하지 못함

2. 삼항 연산자

// condition ? "true인 경우" : "false인 경우"
true ? "참" : "거짓"

3. 단축 속성명: Property Shorthand

const name = 'kim'
const newAge = 30

const obj = {name:name, age: newAge}
// name의 변수 값이 같을 경우 생략 가능
const obj = {name, age: newAge}

4. 전개 구문: Spread Operator

let arr = [1, 2, 3]
// 괄호를 제거하고 배열을 출력
console.log(...arr)

let user = {name: 'kim', age: 30}
let user2 = { ...user, birthday: '123'}

5. 나머지 매개변수

function exam(a, b, c, ...args){
	console.log(...args)
}
exam(1,2,3,4,5,6,7) // 하면 4 5 6 7이 출력

일급 객체로서의 함수

1. 정의: 다른 객체들과 일반적 같은 함수(매개변수, 리턴문으로 출력 등)

2. 변수에 함수를 할당

const sayHello = function() {}

3. 함수를 인자로 다른 함수에 전달 가능

function callFunc(func) {
	// 매개변수로 받은 변수가 사실 함수임
	func()
}

const sayHello = function() {}

callFunc(sayHello)  // sayHello가 출력 됨

// 콜백함수: 매개변수로써 쓰이는 함수
// 고차함수: 함수를 인자로 받거나 return하는 함수
function creatAdder(num) {
	return function(x) {
		return x + num
	}
}

4. 객체에도 함수가 적용

const person = { 
	name: 'kim',
	age: 31, 
	isMarried: true
	sayHello: function() {}
}

person.sayHello() //이렇게 함수 호출이 가능

5. 배열의 요소로 함수 할당

const myArr = [
	function (a, b) {return a + b},
	function (a, b) {return a - b}
]
console.log(myArr[0](2, 3)) // 더하기
console.log(myArr[1](2, 3)) // 빼기

Map(자료구조)

1. 목적: 데이터의 구성, 검색, 사용을 효율적으로 처리

2. key / value 쌍으로 구성되며, key에 어떤 데이터 타입도 다 들어올 수 있음(정렬되어 있기 때문)

3. 기능: 검색, 삭제, 완전한 제거, 여부 확인

const myMap = new Map();
// 추가
myMap.set('key', 'value');
// 검색
myMap.get('key')

// 반복을 위한 메서드 keys, values, entires
for(const key of myMap.keys()) {}
for(const value of myMap.values()) {}
for(const entry of myMap.entries()) {} // 각각의 요소를 배열로 묶음

// 크기 확인
myMap.size
// 특정 키 확인
myMap.has('key')

Set(자료구조): 고유한 값 저장, 중복 x

const mySet = new Set();
// 추가
mySet.add('value')
// 검색
mySet.get
// 크기확인
mySet.size
// 특정 값 확인
mySet.has('value')

// 반복
for(const value of mySet.values()) {}

실행 컨텍스트(스코프, 변수, 객체, 호이스팅)

1. 실행 컨텍스트: 실행할 코드에 제공할 환경 정보들을 모아놓은 객체

  1. 선언된 변수를 위로 끌어올림 = 호이스팅(hoisting)
  2. 외부 환경 정보를 구성
  3. this 값을 설정

2. 컨텍스트의 구성(콜 스택)

// 실행 1번(전역) --> 출력은 3, 2, 1순서로 출력
var a = 1;
function outer() {
	function inner() {
		console.log(a); // undefined
		var a = 3;
	}
	inner(); // 실행 3번
	console.log(a);
}
outer(); // 실행 2번
console.log(a);

3. 실행 컨텍스트에 담기는 정보

  1. VariableEnvironment(변경사항 유지)
    1. 현재 컨텍스트 내의 식별자 정보를 가짐
    2. 외부 환경정보를 가짐
    3. 선언 시점 LE의 snapshot
  2. LexicalEnvironment(변경사항 실시간 반영)
    1. record와 outer를 가짐
  3. ThisBinding: this는 식별자가 바라봐야 할 객체

⇒ 실행 컨텍스트를 생성할 때 VE에 정보를 먼저 담고 LE가 복사해서 실시간으로 사용

 

4. 레코드(식별자 정보)와 호이스팅(=레코드의 수집과정)

  1. 레코드: 식별자, 함수 자체, var로 선언된 변수 식별자
  2. 호이스팅 규칙
    1. 매개변수 및 변수는 선언부(var a)를 호이스팅
    2. 함수 선언은 전체를 호이스팅(표현식은 x)

5. outer(전역 > A > B > C 일 때 콜 스택 이전의 환경)

  1. 스코프: 식별자가 영향을 주는 범위
  2. 스코프 체인: 함수 내부에서 식별자를 찾을 수 없을 때 outer에서 참조하는 행위

콜백 함수(되돌아 와서 호출해 줘!!)

1. 매개 변수로 활용되는 함수(다른 코드의 인자로 넘겨주는 함수)

2. 콜백 함수의 제어권은 다른 함수에 있음(제어권을 가진 함수의 로직에 의해 처리)

 

콜백 함수 - 제어권

1. 인자에 대한 제어권(콜백 함수가 아닌 map 함수에 있음)

//map: 기존 배열을 변경하지 않고 새로운 배열을 생성하는 함수
var newArr = [10, 20, 30].map(function(currenVal, index){
	console.log(currenVal, index); // [10, 20, 30] = currentVal
	return currentVal, index; // map 함수는 return이 없으면 출력 x
});

2. 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정할 경우 그 대상 참조(call)

Array.prototype.map123 = function(callbackFunc, thisArgs) {
	// map 함수에서 return할 결과 배열
	var mappedArr = []

	for(var i=0; i<this.length; i++) { //this = 3(밑에 배열이 3)
		var mappedValue = callback.call(thisArgs || global, this[i])
		mappedArr[i] = mappedValue
	}
	return mappedArr
}
var newArr = [1, 2, 3].map123(function(number) {
	return number * 2
}

콜백 지옥과 동기 비동기 개념

1. 콜백 지옥: 들여 쓰기 수준이 지속적으로 깊어져서 이해하기 어려운 경우(비동기 작업에서 발생)

2. 동기: 코드가 실행된 순서대로 진행되며, 앞의 코드가 끝나지 않으면 뒤의 코드가 실행 x

3. 비동기: 앞의 코드가 끝나지 않더라도 다음 코드가 먼저 수행되면 출력

 

비동기 작업의 동기적 표현 - Promise

1. 비동기 처리에 대해, 처리가 끝나면 알려달라는 약속

new Promise(function(resolve){{
	setTimeout(function(){
	var name = "에스프레소"
	console.log(name)
	
	resolve(name); // 이 부분이 찍혀야 다음으로 넘어감
	}, 500)
}).then(function(prevName){
	// 안에서 새롭게 promise를 만듬
	return new Promise(function(resolve){
		setTimeout(function(){
			var name = prevName + " ,에스프레소"
			console.log(name)
	
			resolve(name); // 이 부분이 찍혀야 다음으로 넘어감
		}, 500)
	}) 
}).then(똑같이 )

// 위의 코드는 꼬리에 꼬리를 무는 형식으로 이루어짐
// Promise() -> resolve(인자)를 만나면 코드가 아래로 진행되며, 
// then이 위의 코드를 받은 뒤에 실행


// refactoring
var addCoffee = function(name) {
	return function(prevName){
			// 안에서 새롭게 promise를 만듬
			return new Promise(function(resolve){
			setTimeout(function(){
				// 빽틱
				var newName = preName ? `${prevName}, ${name}` : name
				//var newName = prevName + name
				console.log(newName)
	
				resolve(name); // 이 부분이 찍혀야 다음으로 넘어감
			}, 500)
	}) 
}
addCoffee("에스프레소")()  // 두 번째 리턴문을 실행
	.then(addCoffee("아메리카노"))
	.then(addCoffee("카페라떼"))

콜백 함수 - 제너레이터

1. 제너레이터: Iterator 객체를 반환

2. 비동기를 동기로 바꾸는 이유: 순서를 보장받기 위해서

// 제너레이터 함수 안에서 쓸 함수
var addCoffee = function(prevName, name) {
	setTimeout(function(){
		coffeeMaker.next(PrevName ? PrevName + name : name
	}, 500);
};

// 제너레이터 함수 선언
// *이 붙은 함수가 제너레이터 함수이며 이터레이터 객체가 반환됨
var coffeeGenerator = function* () { 
	// yield를 만나면 addCoffee()가 완료될 때까지 기다림
	var espresso = yield addCoffee("", "에스프레소");
	console.log(espresso);
	var americano = yield addCoffee(espresso, "아메리카노")
};

var coffeeMaker = coffeeGenerator();
coffeeMaker.next();

콜백 함수 - async awit

var addCoffee = function(name) {
	return new Promise(function(resolve) {
	setTimeout(function() {
		resolve(name)
	}, 500)
	})
}

// async = asyncronos
var coffeeMaker = async function() {
	var coffeeList = ""
	var _addCoffee = async function(name) {
		coffeeList += (coffeeList ? ", " : "" + (await addCoffee(name))
	}
	await _addCoffee("에스프레소")
	console.log(coffeeList)
	await _addCoffee("아메리카노")
	console.log(coffeeList)
} // async가 붙은 함수는 await를 만나면 끝날 때까지 기다려야 함
	// 이 때 함수는 항상 Promise를 반환해야 함
coffeeMaker();
728x90