TIL : 23.01.25

jin·2023년 1월 25일
0

TIL

목록 보기
10/39
post-thumbnail

23.01.18-23.01.26 언어학습 주차 / this, callback

this

this는 기본적으로 전역(window)이다. 일반 함수 내에서 혼자 this를 선언하면, 그 this는 전역(window)객체를 가리킨다.
아래 예시에서 객체 메서드 a 안의 this는 객체 obj를 가리킨다. 객체의 메서드를 호출할 때 this를 내부적으로 바꿔주기 때문이다.

let obj = {
  a: function() { console.log(this); },
};
obj.a(); // obj

따라서 호출할때 호출하는 함수가 메서드인지, 함수인지가 중요하다.

개념 정리

▪︎ 전역 객체란 무엇을 의미하는 것 일까요?
→ 특정한 객체에 속하지 않는 함수와 속성들로 모든 객체들을 프로퍼티로 갖고 있는 최상위 객체 (window, global)

▪︎ 다른 언어의 객체와 자바스크립트의 객체는 어떻게 다를까요?
→ 자바스크립트는 자바와는 달리 생성자를 통해 객체를 만들수 있을 뿐만 아니라, 객체를 직관적으로 바로 인라인으로 선언하여 사용할수 있다. (유연성이 있다.)

▪︎ 그렇다면 this는 어떻게 달라질까요?
→ 클래스로 생성한 인스턴스를 의미하고 ,클래스에서만 사용할 수 있다. 하지만 자바스크립트 내의 this는 어디서든 사용할 수 있다.
또한, 자바스크립트의 경우 Java와 같이 this에 바인딩되는 객체는 한가지로 고정되는게 아니라 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.

▪︎ 함수와 메서드의 차이에 대해서 조금 더 알게된게 있을까요? 지난번에 했던 답과는 어떻게 다를까요?
→ 지난답 ) 종속성의 차이. 함수는 독립적으로 존재하나 메소드는 클래스 내부에 종속되어있다

  • 함수: 호출하는 객체가 없어 클래스나 객체에 영향을 받지 않고 직접적으로 호출
  • 메소드: 함수를 호출하는 객체가 존재하며 점 또는 대괄호 표기법을 이용해 호출

이번 답) 함수는 그 자체로 독립적인 기능을 수행하고, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다. 둘은 독립성으로 그 차이를 나눌 수 있다.

용어정리

  • 전역, 전역객체 : 특정한 객체에 속하지 않는 함수와 속성들을 일컫는 말로 이 모든 객체를 포함하는 객체를 전역객체라 부름
  • 렉시컬 환경 : 코드 내의 block, function, script를 실행하기 앞서 생성되는 특별한 객체 ( 즉, 우리가 코드를 실행할때 참조가 필요한 변수의 값을 렉시컬환경이라는 객체에서 식별자 이름을 키로 찾는다.)
  • 전역 객체의 렉시컬 환경 : 전역코드가 시작될때, 만들어지는 환경객체로 코드를 실행하기 전 앞서 선언된 변수와 함수를 먼저 전역환경레코드에 저장
  • 메소드 : 자신을 호출하는 대상 객체가 존재하며, 이 대상객체에 관한 동작을 수행하는 함수
  • 함수 : 특정 객체가 호출하지 않아도 스스로 호출이 가능한 독립적인 함수
  • 프로퍼티 : 이름과 값을 가진 값으로써 다른값과 연결된 어떠한 값을 의미
  • 할당 : assignment 값을 부여함을 의미
  • 호출 : 값을 불러옴을 의미

Q&A 답하기

Q1. 책에서 self 변수로 선언을 해서 만들어서 구현하려고 했던 'this'는 어떤 것 때문에 그렇게 구현했을까요?
: 호출의 주체가 없을 때, 전역객체 호출대신 내부에 this를 직접적으로 상속할 수 있는 방법이 없어 우회하기 위해 사용된 것으로 보여진다.

Q2. 다시 함수와 메서드의 차이를 말씀해주세요
: 함수는 그 자체로 독립적인 기능을 수행하고, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다. 둘은 독립성으로 그 차이를 나눌 수 있다.

Q3. 프로퍼티에 할당, 메서드로서의 호출을 설명해주세요
: 점표기법이든, 대괄호 표기법이든 어떤 함수를 호출할때 그 함수 이름앞에 객체가 명시되어 있는 경우에는 메서드로 호출한 것이고, 그렇지 않은 모든 경우에는 함수로 호출한 것이다.
함수로서 호출하는 경우에는 this가 지정되지 않아 전역 객체를 가리키고, 메서드로서 호출하는 경우는 호출의 주체가 바로 함수명 앞의 객체이므로 점 표기법일 경우 점 앞의 객체가 곧 this가 된다.

⭐️화살표 함수는 상위함수의 실행유지 목적으로 만들어진 함수로 자체적 실행 문맥을 가지지 않기 때문에 외부 상위스코프 함수의 this를 상속 받는다.

Q4. "this 가 주는 인상"이라는 개념을 본인이 생각한대로 아는만큼 작성해주세요.
기본적으로 this는 window를 가리키기 때문에 함수의 호출 환경이 this에 가장 큰영향을 미친다.
this가 어디서 오는지 보단, 이 함수가 어떻게 실행되는가를. 화살표의 경우 화살표함수가 정의된 곳의 문맥은?을 생각하자.

스터디 2조 내부 토론(1)

1. this란?
: this란 ‘이것’ 이며, JavaScript의 예약어이다.
: this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.
2. this 바인딩이란?
: this와 this가 가리키는 객체를 호출시 동적으로 연결해주는 방법
3. this가 동적으로 바인딩 된다… 바인딩 된 객체는 어떻게 다른가요? ⭐⭐⭐
: 일반적으로 전역객체를 가리키나 호출의 주체에 따라 달라진다.
: 함수에서는 전역객체를, 메소드에서는 명시된 객체를, 화살표함수에서는 상위스코프함수를 바인딩 한다.
4. 화살표함수에서의 this는 어떻게 작동할까요?
: 상위 스코프 함수를 상속받는다.


콜백함수

개념 정리

▪︎ 프로그래밍의 제어권이라는 것은 무엇을 말하는 걸까요?
→ 제어권을 받게 될 경우 호출 시점 , 호출할 값, 호출의 순서, this의 지정 과 같은 요소들을 지정할 수 있게 된다

콜백 함수에서 제어권을 넘겨 받으면?
☑︎ 콜백함수의 호출시점을 스스로 판단해서 실행
☑︎ 콜백 함수를 호출할때 인자로 넘겨준 값과 순서 지정
☑︎ this가 무엇을 가리킬지 지정 (만약 바꾸고 싶다면 bind사용, 지정이 없을 경우 전역객체로 사용)

▪︎ 콜백 지옥이란 뭘까요?
→ 비동기 호출이 자주 일어나는 프로그램의 경우 발생하는 것으로 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들어질 정도로 깊어지는 현상 (Indent depth의 증가)
→ 콜백 함수를 익명 함수로 전달하는 과정에서 또 다시 콜백 안에 함수 호출이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상
→ 콜백 지옥 탈출을 위해서는 promise, promise+async/await를 사용한다.

▪︎ 추상화란 뭘까요?
→ 복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것 (ex. 브라우저 주소창, 교통카드 등)

▪︎ 동기와 비동기의 차이
동기와 비동기

  • JavaScript 엔진은 비동기 함수가 없다.
  • JavaScript 환경에서 제공하는 API를 이용(브라우저, Node.js)
  • JavaScript는 싱글스레드 프로그래밍 언어이기 때문에 콜 스택이 하나 밖에 없다.
  • 이러한 비동기 함수를 제공하고 비동기 함수가 콜 스택에 쌓이도록 도와주는 것은 자바스크립트 런타임(환경)에서 제공되는 것이다.

    비동기 사례
    마우스 및 키보드 입력, 타이머API, 애니메이션API, 페이지로딩 등..

▪︎ 비동기처리를 하는 이유?
비동기 함수는 각각 걸리는 시간이 다르기 때문에 결과를 예상할 수 없다.
따라서 콜백의 순서를 제어하기 위해 사용한다.

function fn() {
  console.log('하나');
  setTimeout(() => console.log('둘'), 0);
  console.log('셋');
}

fn() // 결과 순서 => '하나', '셋', '둘'

▪︎ promise+async/await

  • Promise는 new 연산자와 함께 호출하고 인자로 콜백을 받는다.
  • PromisePromise를 반환한다.
  • Promise는 호출될 때 바로 실행되지만 그 안에 콜백은 resolve, reject 둘 중 하나가 호출 되기 전에 then 또는 catch로 넘어가지 않는다.
// Promise 기본 패턴 1 : 성공인 경우
function fn() {
  new Promise((resolve, reject) => {
    console.log('하나');
    // 실패인 경우 reject() 함수를 호출하면 된다.
    // 그러면 then()을 건너뛰고 catch()가 실행된다.
    resolve(); 
  })
  .then(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('둘');
        resolve();
      }, 0);
    });
  })
  .then(() => {
    console.log('셋');
  })
  .catch((err) => {
    console.log('err ', err);
  });
}
  • 비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고, 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await을 표기하는 것만으로 뒤의 내용을 Promise로 자동 전환하고 해당 내용이 resolve된 이후에야 다음으로 진행된다.
// '하나둘셋넷' 텍스트 이어서 출력하기
// 중요 포인트 1 : return을 하지 않았어도 자동으로 fn함수는 Promise를 return 한다.
// 중요 포인트 2 : await을 붙이 Promise는 Promise를 리턴하지 않는다. (resole에 인자로 전달한 데이터를 리턴한다.)
async function fn() {
  let text = '하나';
  text = text + await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('둘');
    }, 0);
  });
  text += '셋';
  console.log(text + '넷');
}

용어정리

  • 제어권 : 선언, 호출, 할당 등에 있어 부여, 통제권을 갖는 능력
  • 콜백함수 : 다른 함수(caller)의 인자(argument)로 전달되는 함수로써 콜백함수의 코드를 받은 함수는 적절한 시점에 필요에 따라 콜백함수를 실행 (간단하게 콜백 함수는 알람같은 함수다!)
  • 고차함수 :  함수를 인자(argument)로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수
  • 콜백지옥 : 콜백함수를 과도하게 사용했을때 나타나는 현상으로 가독성이 떨어지고, 디버깅이 어려워지게 된다.

[복습]
callback? :다른함수가 실행을 끝낸뒤 실행되는 함수(함수를 연결하는 것(ㅇ), 함수실행을 연결하는것(x)
필요성? :자바스크립트가 이벤트 기반 언어이므로 다음 명령어 실행전 이전 명령을 기다리기 보단, 계속해서 실행한다. 이때 콜백은 특정 코드가 끝나기 전까지는 다른 코드가 실행되지 않게 하기 위해 쓰인다.
사용? :콜백은 API를 사용할때 가장 많이 쓰인다. (ex. get, post, request .etc)


클로저(closure)

정의

예시를 통해 살펴보자.

let one; 					// 선언된 변수는 전역 L.E로 향하며 아직 초기화 되지않아 undefined를 갖게 된다.
one=1;						// 1이라는 값을 할당해주었으므로 1을 갖게 된다.
function addOne(num){		// 변수와 달리 선언시 바로 초기화가 되어 사용이 가능하다.
	console.log(one+num);	// 먼저 내부에서 찾고, 그 다음 외부에서 찾음.
}
addOne(5); 					// 새로운 내부 L.E가 생성된다. 내부는 외부를 참조한다.

클로저알아보기

클로저란?
: 클로저에 의해 참조되는 외부함수의 변수를 자유변수라고 하는데, 이때 자유변수에 엮여있는 함수를 클로저라고 한다.
다른 정의)

  • 함수와 그 함수의 렉시컬 환경의 조합
  • 함수가 생성될 당시의 외부변수를 기억하는 기능
  • 생성 이후에도 계속 접근 가능

클로저의 장점
1. 데이터를 보존할 수 있다.
: 클로저 함수는 외부함수의 실행이 끝나더라도 외부함수 내의 변수를 사용할 수 있다. (특정 데이터를 스코프 안에 가두어 둔채 사용하게 하는 폐쇄성)
2. 정보의 접근 제한 (캡슐화)
: 클로저 모듈 패턴을 사용해 객체에 담아 둔 후, 여러개의 함수를 리턴한다.
3. 모듈화에 유리
: 클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용하고 보존할 수 있다.

클로저의 단점
실행시마다 각자의 참조영역이 유지되어야 하므로 메모리 사용량이 늘어난다.

클로저 총 정리

  • Closure는 function 안에 function이 있게 되면 기본적으로 생성된다.
  • Closure는 scope chain이 생성됐을 때의 변수 값들을 보존하고 기억하게 된다.
  • 함수가 메모리에서 없어질 때까지 따라다니게 된다.
  • 같은 모양의 함수이더라도 다른 closure를 가지고 있을 수 있다.
  • 함수가 다른 곳에서 사용되더라도 처음에 생성되었던 scope chain이 끝가지 따라다니게 된다.
  • 다른 곳에서 사용되는 대표적인 경우: 함수를 리턴하여 사용, 다른 함수의 인자로 넘겨줘서 사용, 콜백으로 사용

스터디 2조 내부 토론(2)

1. callback?
:다른함수가 실행을 끝낸뒤 실행되는 함수(함수를 연결하는 것(ㅇ), 함수실행을 연결하는것(x)
2. 콜백함수에서 제어권을 받으면 할 수 있는 일은?
: 호출시점정하기, 호출할때 넘겨준 값과 순서를 정하기. this가 무엇을 가리킬지 정하기(바꿀경우 bind사용, 미지정시 전역객체지정)
3. 클로저가 뭔가요?
외부 함수보다 중첨 함수가 더 오래 유지되는 경우 중첨 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저라고 한다.
4. 클로저의 장점?
데이터 보존, 모듈화, 캡슐화
5. 클로저의 생성방법?
외부함수 생성 ⇢ 내부함수 생성, 외부함수에서 내부함수 리턴
⇢ 내부 함수에서 외부함수의 변수에 접근

☑️ 오늘 내용의 경우 복잡한 개념이기 때문에 복습필수!

profile
。˚⋆。˚ ☁︎˚。⋆。˚☽˚。⋆˚ ☁︎˚

0개의 댓글