티스토리 뷰

javascript

this, arrow function

kmj24 2021. 6. 25. 00:12

Javascript에서 this의 값은 함수를 호출한 방법에 의해 결정된다.

실행중에는 할당으로 설정할 수 없고 함수를 호출할 때 마다 다를 수 있다.

ES5에서 함수를 어떻게 호출했는지 상관없이 thist 값을 설정할 수 있는 bind method를 도입했고, ES2015는 스스로의 this 바인딩을 제공하지 않는 arrow function을 추가했다.

 

this

this는 상황에 따라 다른 값을 반환하므로 우리를 어렵게 한다.

this는 어떤 객체에 호출되느냐에 따라 의미가 달라진다.

실행 컨텍스트의 property는 비엄격 모드에서 항상 객체를 참조하며, 엄격모드에서는 어떠한 값이든 될 수 있다.

 - 전역 문맥에서 this는 전역객체를 참조한다. window를 참조하는 것이다.

 - 함수 문맥에서는 함수를 호출한 방법에 의해 this가 좌우된다.

 - 함수가 호출될 때 마다 this가 결정되는 것은 this가 해당 객체에 바인딩된다는 의미이다.

 - this는 함수의 Lexical scope를 참조하지 않는다.

 - 아래의 코드는 this.temp가 어떤것인지 모르므로 undefined출력, 엄격모드에서는 참조 오류가 발생한다.

function thisTest(){
    let temp = 1;
    call();
}
function call(){
    console.log(this.temp);
}
thisTest();

 

 

this는 기본 바인딩, 암시적 바인딩, 명시적 바인딩, new 바인딩 4가지 규칙에 의해 바인딩 된다.

기본바인딩

 - 함수를 단독 실행하는 경우이다.

 - this는 전역객체를 가리킨다.

 - 엄격모드에서는 undefined가 된다.

암시적 바인딩

 - 객체의 메서드로써 바인딩 되는 방식이다.

 - 아래의  코드에서 this는 obj가 된다.

const obj ={
    a : "a",
    b : function() {
        console.log(this);
    }
}
function thisTest(){
    obj.b();
}
thisTest();

 - 아래의 코드에서 this는 undefined가 된다.

const obj ={
    a : "a",
    b : function() {
        console.log(this);
    }
}
function thisTest(callback){
    callback();
}
thisTest(obj.b);

 - call 함수에 인자로 obj.b를 넣어 주었지만 parameter로 받아온 함수는 단독 실행되므로 this가 가리키는것은 window가  된다.

 - 이를 암시적 소실 이라고 한다.

 

명시적 바인딩

 - 위의 암시적 소실을 방지하기 위한 내장함수인 call(), apply(), bind()를 사용하여 명시적으로 this를 바인딩 할수 있다.

 - call()과 apply()는 첫번째paramter로 this를 바인딩할 객체를 직접 전달 받는다.

 - call()은 두번째 ~ n번째 인자로 기존 함수에 전달할 인자를 넘겨준다.

 - apply()는 두번째 인자로 배열 형식을 기존 함수에 전달할 인자로 넘겨준다.

 - bind()는 인자로 바인딩할 객체를 넘겨준다.

 - bind()는 함수가 가리키는 this만 바꾸고 함수를 호출하지는 않는다. 따라서 변수에 할당하여 해당 변수를 호출하는 형태로 사용한다.

 

new 바인딩

 - javascript에서 new는 다음과 같은 과정을 거친다

 1. 새로운 객체 생성

 2. 새로 생성된 객체의 prototype이 연결

 3. 새로 생성된 객체는 해당 함수 호출 시 this로 바인딩

 4. new와 함께 호출된 함수는 자동으로 새로 생성된 객체를 반환

 - new는 함수 호출 시 새로 생성된 객체와 this를 바인딩 한다.

 - 아래의 코드는 문자열 "test"를 출력한다.

function thisTest(){
    this.name = "test";
}
const test = new thisTest();
console.log(test.name);

 

this 테스트 코드

const object = {
    name : "OBJ",
    whoami: function () {
        console.log(this);
        const thisTest = () =>{
            console.log(this);
        }
        thisTest();
    }
}

function thisTest(test: Function){
    test();
}
function bindTest(name: string, pw: string){
    this.name = tmp;
    this.pw = pw;
}
function callTest(test: string){
    console.log(`call binding this.name : ${this.name}, this.pw : ${this.pw}`);
    console.log(test);
}

function applyTest(test1: string, test2: string){
    console.log(`${this.name}, ${this.pw}`);
    console.log(test1);
    console.log(test2);
}

function thisRun(){
    //암시적 바인딩 => this는 this가 속해있는 Object를 가리킨다.
    object.whoami();
    
    //암시적 소실 => this는 window를 가리킨다. (script mode => undefined)
    thisTest(object.whoami);

    // new => 함수를 객체로 만들어 준다. this는 해당 객체를 가리킨다.
    let newBinding = new bindTest("name", "pw");
    console.log(`${newBinding.name}, ${newBinding.pw}`);

    // call/apply binding => 첫번째 arg로 객체를 넣어주며 두번째 인자값은 바인딩할 함수가 받을 parameter
    // this는 첫번째 arg로 넘겨준 객체를 가리킨다.
    callTest.call(newBinding, "test");
    applyTest.apply(newBinding, ["arg1", "arg2"]);
}

thisRun();

 

 

Arrow function

화살표 함수는 일반함수와 this를 바인딩하는 방식이 다르다.

일반 함수는 위에서 설명한 바인딩 방식을 모두 따르지만 화살표 함수는 항상 선언된 위치의 상위를 가리킨다.

//여기서 출력되는 this는 obj를 가리킨다.
const obj = {
    a : "a",
    b : function () {
        console.log(this);
    }
}
obj.b();

//여기서 출력되는 this는 window를 가리킨다.
const obj = {
    a : "a",
    b : () => {
        console.log(this);
    }
}
obj.b();

//여기서 this는 obj를 가리킨다.
const obj = {
    a: "a",
    b: function () {
        const tmp = () => {
            console.log(this);
        }
        tmp();
    }
}
obj.b();

//여기서 this는 window를 가리킨다.
const obj = {
    a: "a",
    b: () => {
        const tmp = () => {
            console.log(this);
        }
        tmp();
    }
}
obj.b();

//여기서 this는 undefined
const obj = {
    a: "a",
    b: () => {
        function tmp () {
            console.log(this);
        }
        tmp();
    }
}
obj.b();

//여기서 this는 window를 가리킨다.
const obj = {
    a: "a",
    b:  () => {
        const tmp = () => {
            const tmp2 = () =>{
                console.log(this);
            }
            tmp2();
        }
        tmp();
    }
}
obj.b();

//여기서 this는 obj를 가리킨다.
const obj = {
    a: "a",
    b:  function (){
        const tmp = () => {
            const tmp2 = () =>{
                console.log(this);
            }
            tmp2();
        }
        tmp();
    }
}
obj.b();

//여기서는 undefined
function test(){
    const tmp = () => {
        console.log(this);
    }
    tmp();
}
test();

위와 같이 여러번 테스트 해본 결과 화살표 함수는 항상 window를 가리키려 하며 
object에서 일반 function으로 감싸진 화살표 함수 내의 this는 object를 가리킨다.
또한 object에서 화살표 함수로 감싸진 화살표 함수 내의 this는 window를 가리킴을 알수 있다.

 

 

 

참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

 

this - JavaScript | MDN

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

developer.mozilla.org

https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd

 

(JavaScript) 함수의 메소드와 arguments - call, apply, bind

안녕하세요. 이번 시간에는 함수의 메소드에 대해 알아보겠습니다. 초보 강좌에서 숫자, 배열, 문자열에 대한 메소드에 대해서만 알려드렸죠. 함수에도 기본 메소드가 있습니다. 하지만 초보 강

www.zerocho.com

 

'javascript' 카테고리의 다른 글

Javascript currying  (0) 2021.06.26
Javascript와 비동기(asyncronous), Callback/Promise/async await  (0) 2021.06.25
Event Loop  (0) 2021.05.11
closer function  (0) 2021.04.28
Hoisting  (0) 2021.04.20
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함