TIL : this, 전개구문, method

hihyeon_cho·2022년 12월 1일
1

TIL

목록 보기
24/101

this

상황에 따라 달라지는 this

: this는 실행컨텍스트가 생성될 때 결정 (this binding) === this는 함수를 호출할 때 결정된다.

  • 전역 공간에서의 this
    1. 전역공간에서 this는 전역객체를 가리킴
    2. 브라우저환경에서는 window객체를 가리키고, node환경에서는 global(node환경)을 가리킴
  • 메서드로서 호출할때 그 내부에서의 this
    • 함수(독립적으로 시행) vs 메서드
      1. 기준 : 독립성
      2. 함수 : 함수명 자체로 독립적인 기능을 수행
      3. 매서드
      : 자신을 호출한 대상 객체에 관한 동작을 수행 ex)obj1.함수명()
      ⇩⇩⇩
      함수로서 호출된 경우 this는 window객체를 의미.
      메소드를 호출한 주체는 obj객체이다.
      함수로서의 호출은 독립적이고,
      메서드로서의 호출은 . []으로, this=obj객체가 반환되는 것이다.

매서드 내부에서의 this

: 메서드의 내부라고 해도, 함수로서 호출한다면 this는 전역객체

함수에서의this

  • 주체가 없기 때문에 호출의 주체를 명시할 수 없다.
  • this가 지정이 되려면 주체가 명확해야하기 때문에 함수의 this는 window가 된다.

this binding

: 함수를 실행하는 당시의 주변환경보다 해당함수를 호출하는 구문앞에 점 또는 대괄호 표기가 있는지가 관건이다!

메서드의ㅡ 내부함수에서의 this 우회

  • 화살표함수
    : function키워드가 아닌 화살표함수로 호출되기 때문에 this 바인딩하는 과정을 스킵하게 됨. 그래서 여기서의 this는 윈도우가 아닌 obj가 출력되는 것.
  • 콜백함수 호출
    : setTimeout함수 혹은 forEach메서드(함수자체이기때문에 window)는 대상이 되는 this를 지정하지 않으므로 this는 곧 window객체이다.
    addEventListener메서드는 콜백함수 호출시 자신의 this를 상속하게 됨. 그래서 this는 addEventListener의 앞부분이 된다.

생성자 함수 내부에서의 this

생성자 : 구체적인 인스턴스를 만들기 위한 일종의 틀 ( constructor ⇒ 구성하는 것 )

  • 생성자 함수 내부에서의 this는 인스턴스(=생성된 오브젝트)를 가리킨다.

명시적 this 바인딩

  • call 메서드

    1. 호출주체인 함수를 즉시실행
    2. func.call({x:1},4,5,6}; ⇒ 콜 메서드를 통해서 인자를 주기전에 내가 원하는(임의의) this바인딩 할 수 있는 객체를 넣어주는 것이다. 그래서 console.log(this,a,b,c)에서 this에 {x:1}이 찍히게 됨
  • apply 메서드

    1. 여러 인수를 묶어 하나의 배열로 전달할 때 apply 사용
       //Math.max(2,3,7) ⇒ 7을 반환( 배열이 아닌 인자들을 , 로 구분)
         var numbers = [ 10,20, 3, 15, 58 ];
        //Math.max는 배열에적용 못하니까 apply 사용
        //this는 없으니까 null로 적용
         var max = Math.max.apply(null, numbers;)
         var min = Math.min.apply(null, numbers;)
         console.log(max,min) // 58 , 3 
  • call/apply 메서드 활용

    1. 유사배열 객체에 배열 메서드를 적용
    2. 유사배열의 조건?
      • 반드시 length가 필요 (필수 )
      • index번호가 0번부터 시작해서 1씩 증가해야함
  • slice() 함수
    1. 배열로부터 특정범위를 복사한 값들을 담고있는 새로운 배열을 만드는데 사용. 첫번째 인자는 시작인덱스, 두번째 인자는 종료인덱스를 받으며, 시작부터 종료 인덱스까지 값을 복사하여 반환
    2. ()안쓰면 전체 복사!!!

  • forEach

    배열.forEach(funtion(arg) {
        console.log(arg)
    }, this) // ⇒ this는 생략가능
  • bind 메서드
    : call과 비슷하지만 즉시호출하진 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하는 메서드

      var func = function (a,b,c,d){
      console.log(this,a,b,c,d);
      };
      func(1,2,3,4); // 함수니까 window객체
      var bindFunc1 = func.bind({x:1});
      //.bind메서드를 이용하면은 매개변수 자리에 this 바인딩으로 사용할 객체를 넣을 수 있다.
      //그래서 this에 {x:1}이라는 값을 넘겨준 것. =>새로운 함수를 반환하여 bindFunc1에 할당을 한다.
      bindFunc1(5,6,7,8); //{x:1} 5 6 7 8
      //위에있는 func가 실행 => this는 {x:1}이니까 뒤에 5678이 반환됨
             
      var bindFunc2 = func.bind({x:1},4,5);
      bindFunc2(6,7); //{x:1} 4 5 6 7
      bindFunc2(8,9); //{x:1} 4 5 8 9
       // 위와같이 부분적으로 변경할 수 있다. 
    
     console.log(func.name); // func
     console.log(bindFunc.name); //bound func
  • name 프로퍼티

    1. bind 메서드를 적용해서 새로 만든 함수는 name프로퍼티에 ‘bound’라는 접두어가 붙는다(추적하기 쉬움)

상위 컨텍스트의 this를 내부함수나 콜백함수에 전달하기

  • 내부함수

    1. 메서드의 내부함수에서 메서드의 this를 그대로 사용하기 위한 방법
    2. self등의 변수를 활용한 우회법보다 call, apply,bind를 사용하면 깔끔하게 처리가능
  • 콜백함수

    1. 콜백함수도 함수이기 때문에, 함수가 인자로 전달될대에는 함수 자체로 전달 ⇒ this 유실
    2. bind메서드를 이용해 this를 입맛에 맞게 변경가능
    3. 콜백함수로 넘어가면 콜백함수도 함수이기때문에 함수자체로 전달된다. 즉, this를 잃어버리기 때문에 this를 명료하게 넣어줘야 명시를 해줘야 this가 현재 context에 맞는 this라는 것을 알수가 있어서 console.log에도 올바르게 출력될 수 있다.
  • 화살표 함수

    1. this 우회 (call, apply,bind보다 편한 방법)
    2. 화살표함수를 쓰게되면 this를 바인딩하는 과정이 제외됨되어 편리하다
  • 별도의 인자로 this를 받는 경우

    1. 추가로 this로 지정할 객체를 인자로 지정할 수 있다.
    2. 배열과 관련된 메서드에 많이 존재하며, set,map등의 메서드에서도 일부존재함
    3. this가 상황에 따라서 많이 바뀌어서 this를 추적하기가 힘든데, “forEach문 , “등 이런 명시적인 방법들로 우리가 원하는 것을 유도할 수 있다.

전개구문

const box = {size: "big", color: "red"};

const newBox = { ...box}; 
// {size: "big", color: "red"}
const newBlueBox = {...box, color: "blue" }; 
// {size: "big", color: "blue"}

 을 붙임으로써 newbox에 원래 box안에 가지고 있던 값들이 그대로 복사되어 오는 것을 알 수 있다.

내용을 바꾸고 싶다면(위의 예시에서는 사이즈 혹은 색깔) 뒤에 내용을 추가해주면 바뀌는 것을 확인할 수 있다.

map()

: 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열 반환하기

const array1= [1,4,9,16];

//map 사용
const map1 = array1.map(x=>x*2);

//함수가 적용된 결과로 새로운 배열을 반환합니다.
console.log(map1); //[2, 8, 18, 32]

filter()

: 주어진 함수의 조건을 통과한 모든 요소를 모아 새로운 배열로 반환하기

const fruits= ['사과', '귤', '배', '감', '바나나', '키위'];

//filter 사용
const result = fruits.filter(fruit => fruit.length > 2);

//함수가 적용된 결과로 새로운 배열을 반환합니다.
console.log(result); //['바나나'] 

프로그래머스

function solution(num, k) {
    let num_arr = String(num)
    for (let i = 0; i <= num_arr.length; i++){
        if(Number(num_arr[i]) === k){
            return i + 1 
        } else{
            return -1 
        }
    }
}

if 조건만 넣었을 때는 원하는 결과가 도출이 되더니 else문 넣자마자 모든 값이 -1이 되는 문제가 발생했다...
⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩

function solution(num, k) {
    let num_arr = String(num)
    for (let i = 0; i <= num_arr.length; i++){
        if(Number(num_arr[i]) === k){
            answer = i + 1;
            break; 
        } else{
            answer =  -1 ;
        }
    }
    return answer

그래서 if에서 조건을 만족했을 때, answer값을 저장하고 for문을 break하도록 하고, answer값에 인덱스를 저장해서 마지막에 answer를 return하도록 만들었더니 해결되었다.


function solution(num, k) {
    const num_arr = num.toString();
    const index = num_arr.indexOf(k.toString());
    if(index !== -1){
        return index + 1;
    }else{
    return index;
    }
}

하지만 다른 분들이 푸셨던 대로 indexOf()를 이용해 풀었을때가 코드도 짧아지고 깔끔해졌다. 내장 매서드를 잘 몰라서 처음엔 사용하지 않고 풀었지만, 이번 기회에 메서드를 공부해서 많이 활용해 볼 필요성을 느꼈다.

indexOf()

: indexOf() 메서드는 호출한 String 객체에서 주어진 값과 일치하는 첫 번째 인덱스를 반환합니다. 일치하는 값이 없으면 -1을 반환한다.

const index = num_arr.indexOf(k.toString());
ex) 상수 index는 num_arr(string객체)에서 k.toString()(k를 문자열로 변환한 값)과
일치하는 첫번째 인덱스를 반환한다. 일치하는 게 없을 시, -1을 반환.

출처:MDN

String 과 toString()

: 둘다 문자열로 변환해 주는 역할을 한다.
이 둘의 차이점은
String => 함수
toString() => 메서드 이다.
그래서 사용할 때도

const num_arr = String(num)// String은 괄호안에 매개변수를 넣어주고
const num_arr = num.toString();// toString은 바꿀 변수 뒤에 .을 붙여준다.

오늘도 시간이 너무 훅 지나갔다. 공부하는 시간도 순삭이고, 쉬는 시간도 순삭이다. 목표한 할당량을 채우는 것도, 뒤돌면 아직 공부할게 산더미처럼 쌓여있어서 막막한 기분도 들지만 조급해말고 차근차근 해나가야겠다. 오늘은 팀원들과 프로그래머스를 통해 자바스크립트를 사용해보는 시간을 가졌다. 생각해보니 메서드에 대해서 익힌적이 없어서 메서드공부가 필요함을 느꼈던 감사한 시간이었다. 도장깨기 잘 해나가서 언젠간 자바스크립트를 잘 다룰 수 있는 날이 올거라고 믿는다 🙂 오늘도 긍정회로돌리기 ! ⭐️

profile
코딩은 짜릿해 늘 새로워 ✨

1개의 댓글

comment-user-thumbnail
2022년 12월 2일

꾸준히 지금처럼만이라면 ㅎㅎ자바스크립트 전문가 되실거라 확신합니다~

답글 달기