👨‍💻회고 일기장/🙈멋쟁이사자처럼 회고

07-10 회고록

se'o 2023. 8. 24. 00:42

🐱 함수 표현식 이론

🐶 함수 표현식

// 함수 선언문
function sayHi()

// 함수 표현식
let sayHi = function() {
  alert( "Hello" );
};

함수 표현식은 함수를 생성하고 생성한 함수를 변수에 할당하는 형태이다.

→ 함수는 “”이라서 변수에 할당할 수 있다.

 

 

sayHi() → 함수를 실행한 값을 반환한다.

sayHi → 함수를 실행하지 않고 함수 본문이 출력된다.

const a = sayHi() ⇒ a에 sayHi()의 반환값 ‘hello’가 담긴다.

const b = sayHi ⇒ b는 sayHi 함수(function) 본문이 담긴다.

a는 저장된 값을 가져올 수 있지만 b는 함수 본문이 들어가 있어서 sayHi()처럼 b를 함수처럼 실행할 수 있다. b()

 

🐶 함수의 복사

함수 선언문으로 작성해보기

function sayHi() {   // (1) 함수 생성
  alert( "Hello" );
}

**let func = sayHi;**    // (2) 함수 복사 -> 함수 본문 그대로 넘긴다.

func(); // Hello     // (3) 복사한 함수를 실행한다.
sayHi(); // Hello    //     본래 함수도 정상적으로 실행됩니다.

let func = sayHi; -> sayHi 함수의 본문을 그대로 복사한다.

함수 표현식으로 작성해보기

let sayHi = function() {
  alert( "Hello" );
};

**let func = sayHi;**  // let func = sayHi() 괄호해야 alert가 실행된다.

함수 표현식은 세미콜론을 붙여야 한다.

⇒ ‘문’과 ‘식’의 차이 : 문은 세미콜론을 안붙여도 되지만 식은 세미콜론을 붙여줘야 한다.

 

🐶 콜백 함수

callback 함수 : 함수 본문이 먼저 넘어가고, 이후에 함수 안에서 나중에 실행되는 것. 함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 함수를 나중에 호출한다.

➡️ 함수를 처럼 전달한다.

ask("동의하십니까?", showOk, showCancel); → 인수에 showOk, showCancel 함수 자체를 전달해서 ask 함수의 인자에는 함수가 그대로 들어가게 된다.

 

➡️ 함수 결과값이 아닌 함수 본문이 그대로 들어가는것!!

function ask(question, yes, no) { → ask 함수의 인자 yes, no에 각각 인수에 전달한 showOk, showCancel 함수가 본문 그대로 들어가게 된다.

if (confirm(question)) yes() else no(); → question에 글자가 들어가 있으면 yes함수(showOk)를 실행하고, 아니면 no(showCancel)함수를 실행한다.

⇒ 함수가 값처럼 취급되기 때문에 가능한 것

 

⬇️ 함수표현식으로 간단하게 쓰기

→ 함수를 실행할 때 값으로 함수 본문을 통째로 바로 전달한다.

⚠️ 이 때 argument 순서 바뀌면 안된다!!!!

 ⛅ 변수에 할당한 것처럼 안보이는데 왜 함수 표현식이야?

 ⛅ 변수에 할당한 것처럼 안보이는데 왜 함수 표현식이야?

➡️ 아래 function() 2개가 callback 함수이고,
그 callback 함수들이 위에 ask 함수에서 yes, no에 할당되는 것임! 할당되고 실행이 나중에 되는 것.
딱 보기에 변수에 할당된 것처럼 아니라고 함수 표현식 아니라고 하지 말 것.

 

 

🐶 익명 함수(Anonymous function)

이름 없이 선언한 함수

→ 변수에 할당된 게 아니라 함수 밖에서는 접근할 수 없다.

변수 자체를 함수의 이름으로 쓰는 경우가 많음

➡️ 콜백 함수에서 주로 사용한다.

// 익명 함수
let anonymousFunctionExpression = function(){};

// 유명 함수 : 이름이 존재하는 함수
let namedFunctionExpression = function hello(){
};

→ 변수에 할당된 게 아니라 함수 밖에서는 접근할 수 없다.

 

🐶 함수 선언문, 함수 표현식 차이점

  • 함수 선언문과 함수 표현식 중 무엇을 선택해야 하나요?함수 선언문을 사용하면 가독성도 좋아집니다. 코드에서 let f = function(…) {…}보다 function f(…) {…} 을 찾는 게 더 쉽죠. 함수 선언 방식이 더 “눈길을 사로잡습니다”.
  • 그러나 어떤 이유로 함수 선언 방식이 적합하지 않거나, (위 예제와 같이) 조건에 따라 함수를 선언해야 한다면 함수 표현식을 사용해야 합니다.
  • 제 경험에 따르면 함수 선언문을 이용해 함수를 선언하는 걸 먼저 고려하는 게 좋습니다. 함수 선언문으로 함수를 정의하면, 함수가 선언되기 전에 호출할 수 있어서 코드 구성을 좀 더 자유롭게 할 수 있습니다.

🐔 차이점

  1. 문법 차이

함수 선언문 ⇒ function 키워드 + 중괄호 형태

➡️ 선언 전에 호출할 수 있어서 가독성이 좋고 코드 구성이 비교적 자유롭다.

// 함수 선언문
function sum(a, b) {
  return a + b;
}

함수 표현식 ****⇒ 함수를 생성하고 함수를 변수에 할당하는 형태

➡️ 콜백 함수에서 많이 사용한다(주로 Arrow function으로 사용한다.)

// 함수 표현식
let sum = function(a, b) {     // 함수를 생성해서 변수에 할당한다.
  return a + b;
};

➡️ 함수 선언문은 지양 해야 한다 .. 협업을 하기 때문에

 

2. 미리 호출해서 쓸 수 있음(선언문) vs 선언 이후에 쓸 수 있음(표현식)

함수 선언문함수 본문 전체가 올라간다. 따라서 함수를 호출하면 정상적으로 실행된다.

 

함수 표현식선언한 변수만 올라간다. 값이 할당되기 전까지는 TDZ에 들어가기 때문에 let, const로 선언된 변수들은 할당하기 전까지는 절대 사용할 수 없다. 올라간 변수에는 아직 값이 할당되지 않은 상태이기 때문에 에러가 발생한다.

 

⚠️ 함수를 선언하기 전에 호출해서 쓰는 건 bad case이긴 함. 권장하지 않음.

🧻 sum2를 let이 아닌 var로 선언해서 호이스팅하면 안돼?

➡️ var은 호이스팅 하면 최초값이 undefined가 돼서 sum2가 undefined로 선언된다.
undefined를 호출하면 에러가 발생한다.

 3.  스코프의 영역이 다르다

함수 선언문 → 함수가 선언된 블록 안에서만 어디서 선언하든 실행할 수 있다. 블록 밖에서 함수 선언문을 찾으려고 하면 스코프가 블록 안을 벗어나지 못해 에러가 발생한다.

➡️ 전체가 호이스팅된다.(lexical environment)

 

함수 표현식 → 할당을 나중에 함수 안에서 하기 때문에 블록 밖에서도 함수를 호출할 수 있다.

➡️ 지정된 변수 값(sum)만 올라감

➡️ 할당되기 전까지는 TDZ에 들어가 있는 상태이기 때문에 호출하면 에러가 발생한다.

함수선언문

sum(1,2) // 실행 잘됨

// 함수를 생성해서 변수에 할당한다.
function sum(a, b) {   
  return a + b;

};

함수표현식

sum(1,2) // error

let sum = function(a, b) {   // 함수를 생성해서 변수에 할당한다.
  return a + b;
};

sum(1,2) // 실행 잘됨

let 선언 부분은 호이스팅이 됨 → TDZ 로 이동 → 할당하기 전까지 TDZ에 머무름 → 호출 불가능(할당돼서 TDZ에 나오면 호출 가능)

선언문 표현식

  선언문 표현식
변수 선언 실행 error

 

🐶 요약

  • 함수는 값입니다. 따라서 함수도 값처럼 할당, 복사, 선언할 수 있습니다.
  • “함수 선언(문)” 방식으로 함수를 생성하면, 함수가 독립된 구문 형태로 존재하게 됩니다.(함수 본문이 통채로 들어간다. )
  • “함수 표현식” 방식으로 함수를 생성하면, 함수가 표현식의 일부로 존재하게 됩니다.(어딘가에 값이 들어가서 할당 받은 형태이다.)
  • 함수 선언문은 코드 블록이 실행되기도 전에 처리됩니다. 따라서 블록 내 어디서든 활용 가능합니다.(제일 위로 올라가서 그 아래에서 함수라는 값을 이미 가지게 된다.) ⇒ 권장x
  • 함수 표현식은 실행 흐름이 표현식에 다다랐을 때 만들어집니다.(let 키워드가 위로 올라가고 나중에 할당부를 만나야 그때 실행할 수 있다.)

⇒ 함수를 위에 선언하고 나중에 호출하는 방식 쓰는걸 권장한다. (선언문 방식 권장 안함)


🐱 함수 표현식 실습

🐶 arguments (⇒ rest parameter 와 유사함)

(함수가 만들어준) 함수 안에서만 접근 가능한 인수들의 집합 객체로, 배열과 유사한 형태로 유사배열이다. (유사배열이기 때문에 배열의 메서드를 가져다 쓸 수 없다.) 인수(argument)에 값이 많이 들어갈 때 한 번에 받아서 사용한다. 인수 arguement는 함수 안으로 들어가면 매개변수로 사용 가능 하다

 

🗣️ 그 인수들 내가 한 번에 관리할 수 있게 arguments 만들어서 안에 넣어줄게~

함수 선언문, 함수 표현식 둘 다 arguments를 가진다!! (화살표 함수는 ❌)

🐶 총합(total) 구하기 예제

🐔 for문

// ! 1. 함수 선언문을 함수 표현식을 만들어보기
// 함수 선언 → 일반 함수 (표현)식
let calculateTotal = function (){
  console.log(arguments); // 없어도 상관없음

  //함수 안에서만 접근 가능한 인수들의 집합 객체로서 배열과 유사한 형태를 가지고 있는 것은 ? : arguments

  // arguments 객체를 사용해 함수의 매개변수 없이 아이템 총합 구하기
  let total = 0;
  
  for(let i = 0; i < arguments.length; i++){
    total += arguments[i];
  }
  return total
};

const result = calculateTotal(1000, 500, 200, 6500, 100)

console.log(result);

→ arguments 객체를 사용해 함수의 매개변수 없이 아이템 총합을 구했다

가지고 있는 값들을 arguments가 유사배열로 만들어서 length보다 짧으면 total에 값을 처음부터 순서대로 넣어서 총합을 구한다.

 

 

🐔 for..of

let calculateTotal = function (){
  let total = 0;
//       사용자 지정명
  for(let value of arguments){
    //console.log(value);   // 1000 500 200 6500 100
    total += value;
  }
  return total
};

for..of 문으로 arguments에서 value 값을 하나씩 뽑으면서 total에 값을 더한다.

🐔 call 함수로 forEach 빌려 쓰기

let calculateTotal = function (){
  let total = 0;

  // * 3. forEach 빌려쓰기
  // arguments가 배열이 아니기 때문에 forEach로 돌릴 수 없다.
  // arguments.forEach(item)=>{
  //   console.log(item);
  // }

  //Array 능력중 forEach문을 arguments가 빌려쓰고 값은 함수가 들어간다. => 아이템 순환 처리
  Array.prototype.forEach.call(arguments, function(item){
    //console.log(item);  // 1000 500 200 6500 100
    total += item;
  })

  return total
};

Array.prototype.forEach.call : arguments는 배열이 아닌 유사배열이기 때문에 배열의 메서드를 사용할 수 없다. 따라서 arguments는 call 함수를 통해 Array의 능력인 forEach문을 빌려 써서 순환하면서 item 값을 total에 넣는다.

⚠️ forEach문은 배열만 사용 가능하다는 점 알아두기! 유사배열은 안됨

 

 

🐔 Array의 slice를 빌려 써서 진짜 배열로 만들기(원래는 유사배열), forEach (forEach는 인스턴스 메서드)

// * 4. Array의 힘을 빌리기
  // arguments인 유사배열을 진짜 배열로 만듦
  // 찐 배열이 가지고 있는 능력 중 유사배열인 arguments가 slice를 빌려써서
  // 값을 도려내서 배열에 집어넣어 진짜 배열로 만든다.
  // => 진짜 배열이 됐으므로 배열의 능력을 다 사용할 수 있음(push, pop, reduce..) 
  // Array의 slice 기능으로 arguments 유사 배열을 진짜 배열로 만들고 realArray에 집어넣는다.
  let realArray = Array.prototype.slice.call(arguments)
	// Arr.slice() 배열로 반환

  console.log(realArray);

  realArray.forEach(function(item){
    total += item;   // 콜백함수의 body(내용) 
  })
  return total;
};

arguments가 Array의 slice 기능을 call 함수를 통해 빌려서 값들을 도려내고 도려낸 값들을 배열에 집어넣어 진짜 배열로 만든다. 그리고그 값들을 realArray에 집어넣는다. (⇒ 유사배열을 진짜배열로 만든다.)

➡️ 배열 형태로 바꿔줬기 때문에 forEach문을 쓸 수 있게 된 것!

⚠️ 위 코드에서 function(item)이 콜백함수! forEach는 콜백함수를 반복한다.

  • 🐱 Instance Method, Static Method

Instance Method(인스턴스 메소드) ⇒ 객체를 생성한 이후에 호출이 가능하다.

Static Method(정적 메소드) ⇒ 객체를 생성하지 않고 클래스명.메서드명으로 호출이 가능하다. (ex. Object.entries())

 

🐔 Array.from 사용해 배열로 만들기 → Static 메서드

// * 5. Array.from()
  let realArray = Array.from(arguments);
  console.log(realArray);
  realArray.forEach(function (item) {
	    total += item;
  })

  // Object.prototype.toString()
  // Object.entries()

   return total;
};

Array.from → 배열이 가지는, 배열로 만들어줄 수 있는 static 메서드

Array.from을 사용하면 프로토타입에 접근할 필요도 없고, call 메소 사용할 필요 없이 대상을 배열로 반환해준다.

 

 

⛅ 인스턴스 메서드 → 프로토타입 메서드(.붙여서 자동 코드 뜨면 되고 아니면 안됨) 유틸 메서드 → static 메서드
 💡 정적 메서드 (static 메서드) 종류 검색 해볼 것

 

🐔 spread syntax(spread operator) 활용해 배열로 만들기

// * 6. spread syntax (spread operator) 이용 : 배열 만드는 방법
  // 가장 많이 쓰임(최신이기도 함) 
  // ? => 장점 : 배열 합성이 편함
  // let arr = [10, 50, 100];
  //let realArray = [...arguments, ...arr];  => arguments랑 기존 arr랑 합쳐짐
	let arr = [10, 50, 100];
  let realArray = [...arguments];

  console.log(realArray);
  realArray.forEach(function(item,index){
    total += item;
  })
   return total;
};

→ 배열 안에 담긴 내용을 풀어서 쓴다.

spread syntax의 장점 : 배열 합성이 편하다. ⇒ […arguments, …arr]

최신 방법이기도 하고 가장 많이 쓰인다.

 

 

🐔 array.reduce() → 원하는 값 뽑아내기

let arr = [10, 50, 100];
let realArray = [...arguments];
  
return realArray.reduce((acc, item)=>{
  return acc + item   
}, 0)    // 0 => initValue

// 화살표 함수 활용해 이렇게 줄일 수 있다.
return realArray.reduce((acc, item)=> acc + item, 0)

reduce(acc, item) ⇒ acc : 누적값 / item : 순회하는 아이템들

return acc + item ⇒ 누적값 + 가리키는 값 / 누적값에 아이템들을 하나씩 넣으면서 총합 구하는 방식

initValue : 최초값을 설정해줘야 한다. (return의 끝에 들어감) 0이 아닌 값을 최초값으로 지정할거면 무조건 넣어줘야 한다. 까먹지 말기!!

 

 

🐶 익명 함수 표현식(이름없는 함수 표현식)

→ 기본 표현식 형태

// 익명(이름이 없는) 함수 (표현)식
// console.dir(anonymousFunctionExpression) => 함수 자체 던지면 함수가 튀어나온다.
// dir은 안의 내용을 조회한다. 뭘 갖고 있는지
let anonymousFunctionExpression = function(){

};

익명 함수를 넣었지만 함수 이름으로 조회 함수지만, 객체로 쓸 수 있음. 함수는 객체로부터 만들어졌기 때문에. callback 함수 인수에 바로 쓸 때 많이 사용한다.

  • dir : 뭘 갖고 있는지 안의 내용을 조회한다.

🐶 유명 함수

이름을 가진 함수 표현식으로 선언도 같이 한다.

// 유명(이름을 가진) 함수 (표현)식
let namedFunctionExpression = function hello(){ // hello()
  
};

함수라는 객체에 hello라는 name을 부여한 것이다.

이 함수 객체를 호출하려면 namedFunctionExpression()으로 호출해야한다.

.name을 사용해 함수의 이름 hello를 바로 불러올 수도 있다.

함수도 객체라서 .key를 사용할 수 있다.

🐶 콜백 함수 ⇒ 흐름 알기 ⭐⭐⭐⭐

→ 부모 함수에 인수를 많이 쓴다.

// 콜백 함수 (표현)식
// 매개변수에 callback을 받음
// 정의
let callbackFunctionExpression = function(isActive, callback){
  // 내부적으로 이렇게 실행됨 => callback() = function(){console.log('콜백 함수 실행!');
  // callback();
  
  if(isActive){
    callback();   // 조건을 따진 이후 함수 실행하거나 실행안함 => 콜백함수(나중에 실행됨)
  }
};

// 호출
callbackFunctionExpression(
  true,
  // 첫 번째 인수로 함수 본문을 넘김 (함수 body가 통째로 전달됨)
  function(){
    console.log('콜백 함수 실행!');
  }
);

a(callback1,callback2)
// 콜백은 내부에서 실행되어야 한다.(ex:handleFontSizeDecrease()x)
minus.addEventListener("click", handleFontSizeDecrease);

위 함수에서 주석처리된 **callback()**은 내부적으로 callback() = function(){console.log('콜백 함수 실행!'); 처럼 실행된다.

⚠️ 콜백 함수는 내부에서 실행되어야 한다!!

⬇️ 예제 (원하는 홈페이지 주소로 이동하는 함수 (movePage))

const movePage = function(url,success,fail){

  if(url.match(/http.+www/) && typeof url === 'string'){
    success(url)
  }else{
    fail()
  }
}

movePage(
  'www.naver.com',
  function(url){
    console.log('성공 몇초 뒤 해당 페이지로 이동합니다.');
    
    setTimeout(() => {
      window.location.href = url
    }, 3000);
    
  },
  function(){
    console.log('올바르지 않은 주소입니다.');
    // ????
  }
)

 

🐶 즉시 실행 함수 표현식

즉시 실행 함수(IIFE, Immediately Invoked Function Expression)) : 함수를 생성함과 동시에 즉시 실행한다.

나온 이유 → 변수의 보호를 위해 탄생했다. (캡슐화, 은닉화)

형태 : 소괄호로 함수를 감싼다.

(function () {
    statements
})();

➡️ 즉시 실행 함수에 익명 함수를 사용하는 이유 : 즉시 실행 함수는 선언과 동시에 호출되어 재사용이 불가능하기 때문에 함수에 굳이 이름을 지어줄 필요가 없다.

let IIFE;

// 함수 스코프 형성됨
(function(){
  var x = 10;
  console.log('즉시 함수!');

})()   // 호출부

// console.log(x);  =>  x는 함수 스코프 안에 갇혀 밖에서 접근할 수 없다.
// (캡슐화, 은닉화 => 변수 보호)
// 이거 무슨 예제임,,,
const MASTER = (function (){
  var x = 10;
  console.log('즉시 함수!');

  return '퉤';
  //return {};   => 객체 내보냄
})()

console.log(MASTER);
console.log(MASTER.setKey('새로운 비밀번호'));

 

🐶 클로저(Closure)

내부 함수와 외부 스코프의 변수를 잇는 연결고리. 의도적으로 함수가 특정 스코프에 접근할 수 있도록 정의하는 경우

let a; 
{
 let b = 1;
 a = function(){
  console.log(b);
 }
}
a(); // 1

🐱 화살표 함수(Arrow Function)

화살표 함수 : 함수 표현식에 포함되고, 함수 표현식을 간결하게 쓸 수 있다.

 

화살표 함수의 기본 형태

일반 함수 표현식 ⇒ 변수 = function(){}

화살표 함수 ⇒ 변수 = () ⇒ {}

// 일반 함수
let func = function(arg1, arg2, ...argN) {
  return expression;
};

// 화살표 함수
let func = (arg1, arg2, ...argN) => expression

예시

let sum = (a, b) => { return a + b };
let sum = (a) => ( a + b );
let sum = a => a + b;

/* 위 화살표 함수는 아래 함수의 축약 버전입니다.

let sum = function(a, b) {
  return a + b;
};
*/

alert( sum(1, 2) ); // 3

화살표 함수는 중괄호로 열고 닫으면 return 키워드를 넣어서 사용할 수 있다.

중괄호 없으면 return 생략해도 됨

중괄호 생략 ⇒ 알아서 값 return 하는 것을 내포한다.

 

 

화살표 함수의 특징

  • 중괄호 있으면 undefined를 리턴하므로 return 지시자를 써줘야 한다.
  • 함수 본문이 한 줄인 함수일 땐 화살표 함수를 쓰는게 좋다.
  • 중괄호 없이 작성하면 그 자체로 return 기능을 가지기 때문에 return 지시자를 쓰지 않아도 된다.
  • 인수가 한 개이면 괄호를 생략할 수 있다. (두 개 이상은 써줘야 한다.)
  •  

let sum = (a, b) => { return a + b };

// 일반 함수
let func = function(arg1, arg2, ...argN) {
  return expression;
};

// 화살표 함수
let func = (arg1, arg2, ...argN) => expression

🐱 화살표 함수 실습

🐶 rest parameter ⇒ arguments와 유사

함수 표현식은 arguments가 있지만 arrow function은 arguments가 없다.

arrow function 안에서만 사용할 수 있는 arguments 같은 애 ⇒ rest parameter(나머지 매개변수)

rest parameter : ...args, ...rest, ...children (이름은 짓기 나름)

let calcAllMoney = (...args)=>{   //rest parameter
  let total = 0;

  args.forEach((item)=>{
    total += item;
  })

  return total;
};

(...args)=>{ ⇒ args의 모든 값을 받아서 배열로 만들어준다.

밖에서 …를 쓰면 spread syntax로 인식하고, 매개변수에서 쓰면 rest parameter로 인식한다.

rest parameter는 나머지 값만 가져올 수 있다.

ex) (a, b, …args) ⇒ args에는 a, b를 뺀 나머지 값만 나오게 된다.

나머지 : args

→ a, b에 들어갈 1000, 500을 제외한 200과 2000이 …args에 들어가 200, 2000만 반환된다.

 

 

🐔 …args 예시 + 화살표 함수로 작성해보기

let calcAllMoney = (a, b, ...args)=>{
  return args.reduce(function(acc, item){
    return acc + item;   // 2200
  }, 0)

  // ⬆️  화살표 함수로 쓰기
  // reduce의 콜백 함수에서 acc + item 값을 내뱉는다.
  return args.reduce((acc, item)=>acc + item, 0)   // 2200
};

 

🐶 함수 만드는 방법 3가지(차이점)

🐔 형태

// 1. 함수 선언문
function normalFunction(){
  console.log(this);
}

// 2. 함수 표현식
const expressionFunction = function(){
  console.log(this);
}

// 3. 화살표 함수식
const arrowFunction = ()=>{
  console.log(this);
}
  1. 함수 선언문

    2. 함수 표현식

    3.  화살표 함수식

arguments : (…) 생성자 x , 함수로써의 기능만 수행함 (가벼움, 빠르게 실행됨)

 

 

 🪗 함수 선언문과 함수 표현식은 prototype: {constructor: *f*} 로 정의되어 있지만 화살표 함수식은 정의되어 있지 않다.
 ⇒ **화살표 함수는 생성자(Constructor)를 내장하고 있지 않다는 뜻

화살표 함수는 생성자로서의 기능을 제외하고 함수로서의 기능만을 사용하기 위해 나온 함수이다.
Cunstructor를 내장하지 않아서 가볍고 속도가 훨씬 빠르다.

❓ 생성자가 뭔데???⇒ 객체 생성할 때 사용하는 메소드 
const obj = new Object() ⇒** Object() 객체를 생성해서 해당 객체의 주소를 obj에 넣는다.

 

🪗 console 창에 dir(normalFunction) 형식으로 찍어 차이점을 찾아보았다.

⇒ 함수선언문, 함수표현식과 다르게 화살표함수식 arrowfunction 은 
constructor ( 생성자 )를 내장하고 있지 않다. 
생성자로써의 기능을 제외하고 진짜 함수로써의 기능만 수행하기 위해서.
constructor 을 내장하면 부모의 부모의 등등 기능을 상속받아야하기 때문에 굉장이 무거움.

 

🐶 함수의 양면의 얼굴(두 가지 기능)

const Button  = ()=>{

}
const a = Button()
const b = new Button()

const a = Button() → Button 함수의 리턴값이 a에 할당된다. 리턴값이 없으면 undefined를 반환한다.

 

const b = new Button() → Button() 객체를 생성해서 해당 객체의 주소를 b에 저장한다.

⇒ 일반 함수와 함수 표현식에서 Constructor 기능을 하는 것이 new 이다.

 

const c = new String(’a’) ⇒ 문자열 ‘a’를 담고 있는 String 객체를 생성한다. 그리고 해당 객체의 주소를 c에 저장한다.

🐱 두 가지 기능 분리시키기 위해 나온게 화살표 함수이다!!

 

🐱 this

함수를 만들어서 실행하면 함수 자체도 실행 컨텍스트가 생겨서 그 안에서 환경이 구성된다. 누구는 변수로, 누구는 함수로 지정이 되는 과정을 거친다. 그 과정중에 this라는 애가 바인딩 된다.(묶인다.) this는 변수로 정의하지 않아도 예약어처럼 언제 어디서든 쓸 수 있음. 함수 안에서 this를 찾는 방법은 일반 함수, 화살표 함수에 따라 다름.

일반함수 → 나를 호출한 대상이 this로 들어간다.

화살표 함수 → this를 찾지 않는다. this를 바인딩하지 않기 때문에 부모꺼를 찾아서 가져온다. : 바깥 실행 컨텍스트에 있는 this를 가져온다.

 

🐱 함수 선언문, 함수 표현식, 화살표 함수식 this

→ window (찐 객체) : 전역 객체

브라우저 : window / 노드 : global ⇒ 합해서 global this.

// * 함수 만드는 방법 3가지
// ? 1. 함수 선언문
function normalFunction(){
  console.log(this); // window 객체가 나옴(찐객체)
}

window.normalFunction()   // 일반 함수 -> 윈도우가 호출 시켜줌 => this : window

// ? 2. 함수 표현식 -> 전역 객체가 아니라서 걍 불러야함.
const expressionFunction = function(){
  console.log(this);
}

expressionFunction(); // this => window

// 얘도 일반 함수 -> 윈도우가 호출해서 this는 window 가 담긴다.

// ? 3. 화살표 함수식 -> 함수로서의 일만 해서 가볍다.
const arrowFunction = ()=>{
  console.log(this);
  // window가 나오지만 window에 의해 호출된게 아니라 나 자신이 호출 된것.
  // 여기서의 this는 다 this 없는데? 바인딩 안했는데? 내 부모꺼 누구야
  // 부모는 선언된게 없어서 window(this)로 인식함. => 그래서 window를 가져오는 것.
}

→ 부모를 window로 인식한다.

let callbackFunctionExpression = function(callback){

    callback();

  };

 

한줄평

this를 찾아가는 과정에서 많은 어려움이 있었다. 앞으로의 많은 학습이 필요하다고 느껴진다

'👨‍💻회고 일기장 > 🙈멋쟁이사자처럼 회고' 카테고리의 다른 글

07-11 회고록  (9) 2023.08.28
07-07 회고록  (1) 2023.08.21
07-06 회고록  (0) 2023.08.07
07-05 회고록  (1) 2023.07.13
23-07-04 회고록  (0) 2023.07.07