제육's 휘발성 코딩
article thumbnail
Published 2023. 3. 28. 02:00
[JavaScript] - this 함수 Frontend/JavaScript
반응형

this 함수

자바스크립트에서 this는 실행 컨텍스트가 생성될 때마다 this가 결정됩니다. 즉, 최초에 전역 컨텍스트 생성 시에 window 객체로 한 번 생성하고 이후 함수 실행 컨텍스트에 의해 함수를 호출할 때마다 생성됩니다.

 

전역 스코프에서의 this

전역 컨텍스트가 생성되면서의 this는 브라우저 환경 기준으로 window, Node 에선 global 객체가 됩니다. 

전역 스코프에서의 this

 

console.log(this);              // true
console.log(this === window);   // true

var a = 1;
console.log(this.a);            // 1
console.log(window.a);          // 1
console.log(a);                 // 1

let b = 1;
console.log(this.b);            // undefined
console.log(window.b);          // undefined
console.log(b);                 // true
  • 전역 공간에서 this를 확인해보면 window 객체와 동일하다는 것을 확인할 수 있습니다.

 

var a = 1;
delete window.a;                  // false
console.log(a, window.a, this.a); // 1 1 1

window.b = 1;
delete window.b;                   // true
console.log(b, window.b, this.b);  // Uncaught ReferenceError
  • 삭제 명령 시에 전역 변수는 해당 프로퍼티의 삭제기능을 막아두지만, window 객체의 프로퍼티로 할당한 경우 삭제가 가능합니다. 

 

자바스크립트에선 메서드와 함수의 차이 등 상황에 따라 this가 바인딩됩니다.

함수 : 함수 그 자체로 독립적 기능 수행 

메서드 : 자신을 호출한 대상 객체에 관한 동작 수행  

함수와 메서드에서의 this에 대해 알아보죠. 

 

메서드 내부에서의 this

var obj = {
    methodA: function (x) {console.log(this, x);},
    inner: {
        methodB: function() {console.log(this);}
    }
};

obj.methodA();              // this -> obj
obj['methodA']();           // this -> obj
obj.inner.methodB();        // this -> obj.inner
  • 위 코드는 obj라는 객체를 생성해서 점 표기법과 대괄호 표기법을 이용했습니다.

 

함수 내부에서의 this

var obj1 = {
    outer: function() {
        console.log(this);                  // obj1
        var innerFunc = function() {
            console.log(this);              
        }
        innerFunc();                        // window

        var obj2 = {
            innerMethod: innerFunc
        };
        obj2.innerMethod();                 // obj2
    }
};

obj1.outer();
  • 첫 번째 this는 메서드인 obj1.outer가 호출되면서. 바로 앞 단계인 obj1 ThisBinding이 됩니다. 따라서 이때의 this는 obj1 입니다. 
  • 두 번째 this는 innerFunc() 함수에 대한 실행 컨텍스트가 생성되면서 this가 지정되지 않았으므로 최상위 객체인 Window 객체가 바인딩됩니다.
  • 세 번째 this는  첫 번째 경우와 동일하게 ob2.innerMethod() 메서드가 호출되면서 실행 컨텍스트가 생성되므로, obj2가 바인딩 됩니다.

 


메서드와 함수의 차이는 호출될 때 앞의 객체를 판별하면 간단하게 구별할 수 있습니다.
호출명 앞에 . 또는 대괄호 표기법으로 객체가 명시돼 있는 경우 -> 메서드 호출
그 외의 다른 경우 -> 함수 호출

 

내부함수에서 this 우회 방법

var obj1 = {
    outer: function() {
        console.log(this);                  // outer
        var innerFunc = function() {
            console.log(this);              // window
        };
        innerFunc();                       

        var self = this;
        var innerFunc2 = function() {
            console.log(self);              // outer
        };
        innerFunc2();
    }
};

obj1.outer();
  • ES5에선 this를 자체적으로 상속할 방법이 없지만, 변수를 활용해서 우회할 수 있습니다. 변수명으로 보통 (_this, that, self) 등으로 사용됩니다. 

 

var obj1 = {
    outer: function() {
        console.log(this);                  // outer
        var innerFunc = () => {
            console.log(this);              // outer
        };
        innerFunc();                       

        var innerFunc2 = () => {
            console.log(this);              // outer
        };
        innerFunc2();
    }
};

obj1.outer();
  • ES6에선 화살표 함수( =>)를 사용해서 실행 컨텍스트를 생성할 때 ThisBinding을 사용하지 않고, 상위 스코프의 this를 그대로 활용할 수 있게 되었습니다. 

 

call 메서드 

Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])

call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령어입니다. call 메서드의 첫 번째 인자를 this로 바인딩하고, 이후 인자들을 매개변수로 사용합니다. 

 

var func = function (a, b, c) {
    console.log(this, a, b, c);
};

func(1, 2 ,3);                  // Window {...} , 1, 2, 3
func.call({x : 1}, 4, 5, 6);    // {x : 1}, 4, 5, 6
  • 메서드를 그냥 호출하면 this는 Window 객체를 바인딩하지만, call 메서드를 사용해서 임의 객체를 this로 지정할 수 있습니다.

 

apply 메서드

Function.prototype.apply(thisArg[, argsArray])
  • apply 메서드는 call 메서드와 동일한 기능을 하나, 두 번째 인자를 배열로 받아 처리합니다. 

 

var func = function (a, b, c) {
    console.log(this, a, b, c);
};

func(1, 2 ,3);                      
func.apply({x : 1}, [4, 5, 6]);
  • 두 번째 인자를 배열로 받아 원소를 처리해 줍니다. 

 

bind 메서드

var obj1 = {
    outer: function() {
        var innerFunc2 = function() {
            console.log(this);              // outer
        }.bind(this);
        innerFunc2();
    }
};

obj1.outer();
  • bind 메서드는 ES5에서 추가된 기능으로, this에 원하는 객체를 지정해 줄 수 있습니다. 

 

REFERENCE

http://www.yes24.com/Product/Goods/78586788

 

반응형
profile

제육's 휘발성 코딩

@sasca37

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요! 맞구독은 언제나 환영입니다^^