티스토리 뷰

들어가기 앞서

 

프로그래밍 언어는 만든 사람(서양)의 철학이 많이 들어가있다.(합리주의, 논리?)

절대 불변의 원칙을 세워놓고, 그 것을 기반으로 차곡차곡 쌓아간다.

이 방식의 장점은 복잡한 것이라도 한꺼풀씩 벗겨나가다 보면 이해하고 파악할 수 있다는 것이다.

 

let x = 10;

 

x는 변수, 오른쪽은 number type의 값이다.

→ '값'이라고 정의한 것은 변수에 넣을 수 있다는 원칙. 객체도 값임. 따라서 변수에 넣을 수 있음. 함수도 마찬가지

 

"자바스크립트는 거의 모든 것이 값이다"

 

 

※ 자바스크립트 문법은 크게 두가지 요소로 나뉨

 

  • 식 

코드를 실행하면 결과가 값으로 마무리가 된다. 값들이 서로 계산될 수 있다. 

(3항 연산자는 식이다)

0;
1+ 10;
foo(); //undefined

 

  •  :

마지막에 세미콜론(;)이 붙지 않음. 하나만 알아도 다 할 수 있음(=for문만 알아도 반복문 다 돌릴 수 있는 것)

if() {
	//조건문
}

while() {
	//반복문
}

 


함수

함수란?
코드를 묶고 있는 값 → 함수 호출은 해당 코드가 생명력을 얻고 실행되어 값을 반환하는것

 

모든 함수는 값을 반환한다.

명시적으로 return을 적는다.

명시하지 않으면 undefined를 반환한다.

new 연산자로 호출하면, 명시적으로 return이 없어도 객체를 반환한다.

 

선언문

function foo() {
	return 0;
}

 

 

함수표현식

const bar = function bar() {
	
};

이렇게 변수에 담을 수 있고, 함수를 값으로 취급했기 때문에 뒤에 세미콜론(;)이 붙는다.

bar()라고 호출이 가능하며, 해당 bar는 변수명을 의미한다. 바깥에서는 안쪽 함수이름을 모르기 때문이다.

 

이름 없는 함수, 즉시 실행 함수(IIFE)

 

함수를 값으로 취급할 땐 이름을 생략할 수 있다.

변수에 넣지않고는 이름을 생략할 수 없다.

다만, 괄호 안에 넣으면 가능하다.(ex. 즉시실행함수)

const bar2 = function () {

}

 

함수는 값으로 함수를 전달 받을 수 있다. 함수를 리턴할 수도 있다. 형태와 위치만 다를 뿐, 다 이다. 

 

*재귀호출은 실행되는 함수의 이름을 알아야하기 때문에 이름이 있어야 됨

 

 

콜백함수

어떤 함수에 함수를 인자로 넘겨 함수의 호출을 위임하는 것이다.

 

 

1급 함수

함수를 받아 실행하고, 함수를 리턴하는 함수(=High Order Component)

(*함수합성 : 함수를 실행할 때 함수가 만들어지는 것)

 

 

화살표 함수(Arrow Function, 한줄 함수, 람다식)

const foo = function(x) {
	
}

const bar = function = (x) => {

}
const x = 10;
const y = () => 10;

console.log(x, y());

위 변수 둘다 10을 반환하지만, y는 계산을 할 수 있다.

인자가 하나 있으면 괄호 생략이 가능하다.

한줄로 쓸 때는 반환할 값으로 보기 때문에 return 을 생략할 수 있다.

 

 

Constructor

new 연산자(Constructor) 호출시 매커니즘 : 

빈 객체를 만듦 → 함수한테 빈 객체를 전달(this)  → 동적 바인딩으로  값을 넣음 → 반환값으로 새로 만든 객체(this)를 반환함

 

*new 연산자로 생성한 인스턴스 객체는 instanceof 연산자로 확인 가능하다.

 

그런데 ES6에서 class가 등장! 뚜둔! 명시적이 되었습니다.

class bar {
    constructor() {
    	this.name = 10;
    }
}

함수와 class가 다른 것은 눈에 보이는 것, class는 명시적이다.

new 함수를 강제할 수 없어서 대문자로 구분을 하는데 class는 new 연산자 없이 호출이 불가하여 오류가 나버린다.

 


this

const person = {
	name : 'Emma',
    getName() {
    	return this.name
    }
}

console.log(person.getName()) //'Emma' 반환

this는 실행 컨텍스트, 실행되는 맥락상의 소유자

 

const man = person.getName;

man(); //에러 발생

(소유자가 벗겨진다고 표현함) man을 실행하는 순간 소유자를 알 수 없기 때문에 에러가 발생한다.

이럴 때는 전역객체로 접근한다. 브라우저에서 this는 window객체, node에서는 global이 된다.

 

이럴 때, bind 함수 등을 이용해서 소유자를 고정(?) 시켜준다.

요즘은 bind, call, apply를 잘 안쓰는 추세이다.

 


closure

function foo(x) {
	return function() {
    	return x;
    }
}

const f = foo(10);

f(); //

함수가 실행될 때, 스코프가 생긴다. 안쪽 함수는 바깥함수 스코프 안에 만들어진다.

안쪽 함수는 바깥 함수 스코프 안에 있는 값를 따로 가지고 있다. 즉, 바깥 함수가 종료되어도 closure 영역에 따로 저장을 하고 있다는 것.

보통 값을 보호할 때 많이 사용한다.(캡슐화)

 

클로저 예시

function makePerson() {
    let age = 10;
    
    return {
    	getAge() {
        	return age
        }
        setAge() {
        	age = x > 1 && x < 100 ? x : age;
        }
    }
}

let p = makePerson(); 

console.log(p.getAge()); //age를 클로저에 캡쳐. getAge만이 age에 접근할 수 있다.

 


비동기

setTimeout(function(x) {
	console.log('Ok');
    setTimeout(function(y) {
    	console.log('Ko');
    }, 200)
}, 500); 

//callback hell......

처리를 하다보면 주옥같은 로직이 되어버린다. 콜백헬....!

 

그리고, Promise가 나타났다.

new Promise()를 실행하면 인스턴스 객체를 반환한다.(thenable 객체 = Promise 객체)
resolve는 함수, reject도 함수. resolve가 실행되면 then 안에 함수를 호출하고,  reject가 실행되면 catch 안에 함수를 호출한다.

const p1 = new Promise((resolve, reject) => {
	//내장 함수를 new 연산자로 실행함
    setTimeout(() => {
    	resolve('answer'); // 이것이 바로 클로저!
    }, 1000)
}	

const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    	resolve('answer2'); 
    }, 1000)
}

p1.then(p2)
  .then(function(r) {
      //성공
      console.log(r); // 'answer' 리턴
  }).catch(function() {
      //실패
  }

 

이것도 번거로워서 나온게 비동기함수 async, await

const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) //promise 객체가 리턴됨

async function main() {
    console.log('1');
    await delay(2000);
    console.log('2');
}

main();

async를 붙이면 await를 쓸 수 있다.

Promise 객체가 resolve가 되면 thenable 객체를 리턴받을 수 있는 것이다.

내부적으로는 비동기로 돌아가지만 코드는 동기적으로 돌아가는 것처럼 보이도록 한다.

 


Redux

개념

앱은 수많은 UI요소로 중첩되어 있음.

각각의 요소는 data를 사용하는데, 다른 요소에서도 같은 데이터를 쓰고 싶다면? 이럴 때 데이터를 어디다 두어야할까? Store!

모든 상태를 한 군데 모아놓고 store라고 부르자. 그리고 모든 요소(컴포넌트)에게 데이터를 다 주자.

컴포넌트는 필요한 데이터만 가져다가 화면을 그리면 됨. 컴포넌트는 그릴뿐, 데이터를 바꾸진 못함(immutable)

리액트는 Virtual DOM(VDOM)이 있는데 코드를 VDOM으로 만들고 비교해서 변경 된 부분만 DOM에 반영하기 때문에 가능한 것.

초창기에 나온것이 Flux, 현재 주류는 Redux

 

//redux.js
export function createStore(reducer) {
    //클로저로 상태를 숨겨서 데이터를 변경할 수 있도록함.
    let state;
    const listeners = [];
    const getState = () => ({ ...state }) // 참조가 아닌 복사본을 내보냄. 괄호로 묶어서 값으로 처리
	const dispatch = (action) => {
    	state = retucer(state, action);
        listeners.forEach(fn => fn());
    }
    const subscribe = (fn) => {
    	listeners.push(fn);
    }
    
    return {
    	getState,
        dispatch,
        subscribe
    }
}
//index.js
import { createStore } from './redux';

const INCREMENT = 'increment'; //반복되는거는 상수로 만들자!
const RESET = 'reset';

function reducer(state = {}, action) { 
	//상태를 바꿔주는 코드
    if(action.type === 'increment') {
    	return {
        	...state,
            count: state.count ? state.count + 1 : 1
            //원본을 건드리지 않고 overwrite되어 새로운 객체를 반환함
        }
    } else if(action.type == 'reset') {
    	return {
        	...state,
            count: state.count
        }
    }
    return state;
}

const store = createStore(reducer);
function update() {
	
}
store.subscribe(update);

function actionCreator(type, data) {
	return {
    	...data
     	type: type //뒤에 것이 overwrite될 수 있도록 spread는 앞에 씀
        
    }
}

function increment() {
	store.dispatch(actionCreator(INCREMENT));
}

function reset() {
	store.dispatch(actionCreator(reset, { resetcount: 10 }));
}

//store.dispatch({type: 'increment'});
//store.dispatch({type: INCREMENT }); 
//store.dispatch(actionCreator(INCREMENT));
increment(); 
reset();

console.log(store.getState());

 


 

읽어볼 것

 

자바스크립트의 함수

자바스크립트는 유연함, 모호함, 이상한, 흥미로움 등이 극적으로 뒤섞인 언어다. 가장 많이 쓰이면서도 가장 많은 불평을 듣는 언어이기도 하고 가장 빠르게 변화하고 있는 언어이기도 하다. ��

medium.com

 

프로그래밍 — 단순한 기능, 기능의 결합, 의미의 부여

쉬운 설명을 위해 사칙연산을 하는 함수를 하나씩 만들어볼께요.

medium.com

 

 

{ Code } Playground

 

fastcampus-js-bootcamp.herokuapp.com

 

 

*나중에 확인해볼 것

더보기

React hooks도 클로저

클로저는 구체적으로 쓰로틀링, 디바운스, 커링함수 등에 자주쓰여요 해당 키워드로 검색하시면 클로저의 쓸모에 관해 이해하실 수 있습니다.

*커링 : 여러 인자를 받은 함수를 단일 인자를 가진 함수열로 바꾸는것(feat. 네이버 지식백과). 클로저 개념을 활용한 것.

cost foo = a => b => c => a + b + c;

 

 

잘못된 것이 있다면 알려주세요!🙆🏻‍♀️

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함