[2024.08.14 TIL] JS 기본 문법

박지영·2024년 8월 14일
0

Today I Learned

목록 보기
23/88

📘 JS 기본 문법

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

📃 실행 컨텍스트

  • 스코프, 스코프 체인, outer
    • 스코프 (scope) - 식별자에 대한 유효 범위
    • 스코프 체인 - 식발져의 유효 범위를 안에서 바깥으로 검색 해나가는 것
    • outerEnvironmentReference (=outer)
      • 스코프 체인이 가능하게 하는 것
      • 외부 환경의 참조 정보
  • 스코프 체인
    • outer가 호출된 함수가 선언될 당시의 LE를 참조(환경 정보 저장).
    • 가장 가까운 요소부터 차례로 접근 가능

📃 this (정의, 활용방법, 바인딩, call, apply, bind)

  • this - 클래스로 생성한 인스턴스(클래스로 만들 객체).

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

  • 전역 공간에서의 this

    • this = 전역 객체

    • 런타임 환경에 따른 this

      • node - global 객체

      • browser - window 객체

  • 메소드로 호출될 때 그 내부에서의 this

    • 함수 vs 메소드

      • 독립성
      //함수는 독립적으로 기능 
      함수 - 함수명();
      //메소드는 호출한 대상 객체에 대한 동작 수행
      메소드 - 객체.메소드명();
    • this의 할당

      // CASE1 : 함수
      // 호출 주체를 명시할 수 없기 때문에 this는 전역 객체
      var func = function (x) {
         console.log(this, x);
      };
      func(1); // Window { ... } 1
      // CASE2 : 메서드
      // 호출 주체를 명시할 수 있기 때문에 this는 해당 객체(obj)
      // obj는 곧 { method: f }
      var obj = {
         method: func,
      };
      obj.method(2); // { method: ƒ } 2
      • 함수와 메소드의 호출 구분 - . [] (메소드는 객체.메소드 / 객체[메소드명])
    • 메소드 내부에서의 this

      • this - 호출을 누가 했는지에 대한 정보
    • 함수로서 호출할 때 함수 내부의 this

      • 호출 주체를 알 수 없다.

      • this가 지정되지 않으면 this는 전역 객체

      • 함수를 독립적으로 호출하면 this는 전역 객체다.

    • 메소드의 내부함수에서 this

      • 메소드 내부라고 해도 함수로서 호출하면 this는 전역 객체

        var obj1 = {
          outer: function() {
              console.log('Test => ', this); // (1)
              var innerFunc = function() {
                  console.log('Test => ', this); // (2), (3)
              }
              innerFunc();
        
              var obj2 = {
                  innerMethod: innerFunc
              };
              obj2.innerMethod();
          }
        };
        obj1.outer();
        //Test => [object Object] (1) this === obj1 / 메소드로서 호출
        //Test => [object global] (2) this === global / 함수로서 호출
        //Test => [object Object] (3) this === obj2 / 메소드로서 호출
  • 메소드의 내부 함수에서의 this 우회

    • 변수를 활용하는 방법

      var obj1 = {
          outer: function() {
              console.log(this); // (1) { outer: ƒ }
      
              // AS-IS // 이전 방법
              var innerFunc1 = function() {
                  console.log(this); // (2) 전역객체
              }
              innerFunc1();
      
              // TO-BE // 이후 방법
              var self = this; // this를 변수에 할당해서 활용
              var innerFunc2 = function() {
                  console.log(self); // (3) { outer: ƒ }
              };
              innerFunc2();
          }
      };
      
      // 메서드 호출 부분
      obj1.outer();
    • 화살표 함수(=this를 바인딩하지 않는 함수)

      • 일반 함수롸 화살표 함수의 가장 큰 차이는 this binding 여부

        var obj = {
            outer: function() {
                console.log(this); // (1) obj
                var innerFunc = () => { // this binding 과정이 없었기 때문
                    console.log(this); // (2) obj // 이전 this를 유지
                };
                innerFunc();
            }
        }
        
        obj.outer();
    • 콜백 함수를 호출 시 그 함수 내부에서의 this

      • 어떠한 함수, 메서드의 인자(매개 변수)로 넘겨주는 함수.

      • 콜백 함수의 this도 전역 객체 참조 but this 지정 시 예외적으로 지정한 this를 참조

    • 생성자 함수 내부에서의 this

      • 생성자 - 구체적인 인스턴스를 만들기 위한 틀

        function User(name) {
          // this = {};  (빈 객체가 암시적으로 만들어짐)
        
          // 새로운 프로퍼티를 this에 추가함
          this.name = name;
          this.isAdmin = false;
        
          // return this;  (this가 암시적으로 반환됨)
        }
        let user = new User("보라");
        //위 아래 동일
        /*
        let user = {
          name: "보라",
          isAdmin: false
        };*/
  • 명시적 this binding 및 유사 배열 객체

    • call 메소드

      • 호출 주체인 함수 즉시 실행

      • 첫번째 매개 변수에 this로 binding할 객체를 넣어주면 명시적 this binding

        // call
         var func = function (a, b, c) {
             console.log(this, a, b, c);
         }
        
         //no binding
         func(1,2,3); // 전역 객체 1 2 3
        
         // 명시적 binding
         func.call({x: 1}, 4, 5, 6); // {x : 1} 4 5 6
    • apply 메소드

      • call과 동일 하나 나머지 부분만 배열 형태로

        var obj = {
            a : 1,
            method : function (x, y) {
                console.log(this.a, x, y);
            }
        };
        
        // method 함수 안의 this는 항상 obj
        // apply this binding
        obj.method.apply({a: 2}, [5, 6]); // 2 5 6
    • call / apply 활용

      • 유사 배열 객체(array-like-object)

        • 반드시 length가 필요 / 이 조건은 필수
        • index 번호가 0부터 1씩 증가해야한다.
         var obj = {
            0: 'a',
            1: 'b',
            2: 'c',
            length: 3
        };
        Array.prototype.push.call(obj, 'd');
        console.log(obj); // { 0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4 }
        
        var arr = Array.prototype.slice.call(obj);
        console.log(arr); // [ 'a', 'b', 'c', 'd' ]
      • Array.from

        // 유사배열
         var obj = {
             0: 'a',
             1: 'b',
             2: 'c',
             length: 3
         };
        
         // 객체 -> 배열
         var arr = Array.from(obj);
        
         console.log(arr); // [ 'a', 'b', 'c' ]
    • bind 메소드

      • 함수를 즉시 호출하지 않는다.
      • this 및 인수를 바탕으로 새로운 함수 반환
      • 목적
        • 함수에 this를 미리 적용
        • 부분 적용 함수를 구현
      var func = function (a, b, c, d) {
           console.log(this, a, b, c, d);
       };
       func(1, 2, 3, 4); // 전역 객체 1 2 3 4
      
       // 함수에 this 미리 적용
       var bindFunc1 = func.bind({ x: 1 }); // 즉시 호출x
       bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
      
       // 부분 적용 함수 구현
       var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
       bindFunc2(6, 7); // { x: 1 } 4 5 6 7
       bindFunc2(8, 9); // { x: 1 } 4 5 8 9
      • name property
        • bind를 사용해서 새로만든 함수는 name 속성에 bound라는 접두어가 붙는다.
    • 상위 컨텍스트의 this를 내부 함수나 콜백 함수에 전달

      • 내부 함수

        • 우회법보다 call/apply/bind를 사용

          var obj = {
             outer: function () {
                 console.log(this); // obj
                 //var self = this; 사용 지양
                 var innerFunc = function () {
                     console.log(this);
                 };//.bind(this) // this를 결합한 새 함수 할당
          
                 // call을 이용해서 this 전달
                 innerFunc.call(this); // obj
             }
          };
          obj.outer();
      • 콜백 함수

        • bind로 this 할당
          setTimeout(this.logThis, 1000); // this 유실
          setTimeout(this.logThis.bind(this), 1000); // this binding
      • 화살표 함수의 예외 사항

        • this우회, call, apply, bind보다 편리한 방법
        • 스코프 체인상 가장 가까운 this에 접근
          var obj = {
           outer: function () {
               console.log(this); // obj
               var innerFunc = () => {
                   console.log(this); // obj
               };
               innerFunc();
           }
          };
          obj.outer();
profile
신입 개발자

0개의 댓글