This

성민개발로그·2022년 2월 19일
0

자바스크립트

목록 보기
9/11
post-thumbnail

This란?

자바스크립트에서 모든 함수들이 실행할때마다 함수내부에서 this 라는 객체가 추가된다. this가 참조하는 대상은 함수가 호출하는 방식 마다 다르다.

메소드로 함수를 호출:

var myObject = {
  name: "foo",
  sayName: function() {
    console.log(this);  // 여기서 this는 myObject를 참조 
  }
};
myObject.sayName();
// console> Object {name: "foo", sayName: sayName()}

객체에서 프로퍼티 가 함수면 메소드 라고 칭한다.

메소드 안에서 호출하는 this는 메소드 를 포함한 객체를 가르킨다.

부가설명

Object.Function() 이렇게 메소드로 호출이될때 “ . “(점)바로앞에있는 객체에게 바인딩이 됩니다. 이렇게 바인딩되는 방식을 암시적 바인딩이라고 합니다.

암시적 바인딩으로 사용할때는 저희가 조심히 다뤄야할 부분이 있습니다 바로 메소드를 콜백으로 넘겨줄때 입니다

const obj={
	name: 'sungmin',
	getName() {
        return this.name;
	}
}

function showReturnValue(callback){
    console.log(callback());
}

showReturnValue(obj.getName); //undefined

위 예제를 보시면

callback 이라는 인자가 obj.getName()의 reference (참조값)복제를 했다고 알 수 있습니다. 그래서 callback 은 obj.getName()이란 같은 참조값을 가지고 사용을 한다는것 을 알 수 있습니다. 보시다시피 아예 똑같은 참조값을 통해서 getName()을 참조하는데 왜 이런방식으로 진행하면 this값이 제대로 바인딩이 되지 않는것일까요?

그이유는 바로 “.”(점)연산 때문이다 “.” 을 사용하면 참조타입(Reference Type)이라는 특별한 타입을 사용하게 됩니다.

참조타입은 1. base:객체 2. name:프로퍼티 이름 3. strict: 엄격모드 true

이렇게 세가지 정보를 가지고 있습니다.

그런식으로 obj.getName 이런식으로 된 상태면 (base: obj , name: getName, strict: true) 참조타입은 이런식으로 설정이 됩니다. 여기서 바로 obj.getName()으로 호출을 하게 되면 this가 base 프로퍼티인 obj 를 가리키게 됩니다. 그래서 이러한 방식을 암시적 바인딩이라고 불리웁니다 . 하지만 저희가 점연산이 아닌 위 예제처럼 callback 으로 넘겨서 호출을 하게되면 암시적으로 바인딩된 객체가 휘발이 됩니다. 이런식으로 한두번만 걸쳐도 사라지는 암시적 바인딩을 해결하기 위해서 명시적 바인딩 해주는 방식이 자바스크립트에 있습니다 그 방법은 바로 bind, call, apply 방식으로 명시적 바인딩을 가능하게 해줍니다.

함수로 호출:

var value = 100;
var myObj = {
  value: 1,
  func1: function() {
    console.log(`func1's this.value: ${this.value}`);

    var func2 = function() {
      console.log(`func2's this.value ${this.value}`);
    };
    func2();
  }
};

myObj.func1();
// console> func1's this.value: 1
// console> func2's this.value: 100

메소드 가 아닌 함수로 안에서 this 가 호출이 될때는 this는 전역객체가 바인딩된다.

생성자 함수로 호출:

var Person = function(name) {
  console.log(this);
  this.name = name;
};

var foo = new Person("foo"); // Person
console.log(foo.name); // foo

new 연산자로 함수를 생성할때는 this는 자기자신을 바인딩한다,
new 연산자로 새로운 객체가 생성이된다(인스턴스 생성).

apply, call, bind:

const tom = {
    name: "tom",
    age: 25,
    presentation: function (style, message) {
            console.log("style:"+style+"message:"+message
                        "name:"+this.name+"age:"+this.age);
        },
};

tom.presentation("hip","hello")

const jane={
    name: "jane",
    age: 25,
};

tom.presentation.call(jane, "friendly", "afternoon"); 
//  style:friendly message:afternoon name:jane age:25
tom.presentation.apply(jane, ["friendly", "afternoon"]);
//  style:friendly message:afternoon name:jane age:25 (위랑 같은결과)
let johnFriendy = tom.presentation.bind(jane); 
//bind method -> this를 jane 으로 변경 -> 함수를 실행하지 않는다.
johnFriendy("friendly", "moring");
//  style:friendly message:afternoon name:jane age:25 
  • bind:
    bind는 기존에 this가 참조하고 있는 다른값으로 변경하고 싶을때 사용한다. 바인딩만 되고 실행은 안한다.
  • call:
    call 새로운 this값을 바인딩하고 뒤에 옵션 파라미터를 사용하여 인자를 추가하여 즉시 실행이 가능하다.
  • apply:
    apply는 call 이랑 기능은 똑같은나 뒤에 오션 파라미터가 아닌 배열로 인자를 넘겨줘서 즉시 실행이된다.

this 우선순위

new > 명시적 > 암시적 > 기본

0개의 댓글