[JS] this binding

soor.dev·2021년 4월 13일
0

Java Script

목록 보기
16/26

this

  • 자바스크립트는 스크립트 언어로, 코드를 라인 단위로 읽고. 해석 후 실행시킨다.

  • 실행 컨텍스트 (execution context) : 현재 실행되는 자바스크립트 코드의 환경 혹은 스코프를 말한다.

  • 자바스크립트 내부에서 이런 실행 컨텍스트를 stack으로 관리하고 있으며, 실행되는 시점에 자주 변경되는 실행 컨텍스트를 this(스코프에서의 객체 자신)가 가리킨다.

  • 함수 호출 패턴에 따라 this가 어떤 객체의 this가 될지 정해진다. (binding)


this binding

1) this는 기본적으로 전역객체를 가리킨다.

  • Node 환경에서는 global 객체
  • Browser 에서는 Window 객체

2) 일반적인 함수 내부에서 this를 호출하면 전역 객체를 가리키다.

함수 내부에서 strict 모드를 사용하면, 함수 내부에서 this는 전역 객체를 바인딩하지 않는다.

함수 내부에서 strict 모드를 사용하면, 해당 함수에서의 this는 전역 객체를 바인딩하지 않는다.

함수 외부에서 strict 모드를 사용하면, 모든 함수 내부의 this는 전역 객체를 바인딩하지 않는다.

3) 객체의 메소드 this binding

객체 내부의 메소드에서 this를 binding할 경우, 그 객체 자신을 가리키게 된다.

this 가 참조되는 위치가 아닌, 어디서 this를 포함하는 코드를 호출하는지가 중요하다.

let obj1 = {
    name : 'hyunsoo',
    print() {
        console.log(this.name);
    }
}
let obj2 = {
    name : 'heeni',
    print : obj1.print
};
let name = 'soo';
// [obj1 내부의 this.name 호출]
obj1.print()
// hyunsoo
// [obj2 내부의 this.name 호출]
obj2.print()
// heeni
let print = obj1.print;
// [전역 this.name 호츨]
print()
// soo

어떻게 호출하느냐도 중요하다 !!

let obj = {
    print() {
        console.log(this === obj);
    }
}
let print = obj.print
// [객체의 메소드 방식으로 호출 : this는 obj 객체를 바라봄]
obj.print()
// true
// [일반적인 함수 호출 : this는 전역객체 window를 바라봄 ]
print()
//false

4) new 키워드와 this binding

instance를 호출할 때 각 매개변수 값이 바인딩된다.

binding ?
호출 방법에 의해 결정되는 this를 호출방법과 무관하게 묶어버리는 것 !!

let Person = function(name) {
    if(name.length ===0) {
        this.name = Person.prototype.name
    } else {
        this.name = name
    }
}
Person.prototype.name = 'none';
"none"
let hyunsoo = new Person('hyunsoo')
let heeni = new Person('')
console.log(hyunsoo.name)
// hyunsoo
console.log(heeni.name)
// none

화살표함수를 썼을 때 작동오류??

화살표함수를 쓰면 바깥쪽과 안쪽 this를 같게 만들 수 있다.


call, apply, bind

  • call : 바인딩하면서 함수를 호출, 두번째 인자를 하나씩 받는다.
  • apply : 바인딩하면서 함수를 호출, 두번째 인자로 배열을 받는다.
  • bind. : 바인딩된 함수를 새로 리턴한다.
const you = {
  age: 25,
  gender: 'man',
};

function printYourself(name, gender) {
  console.log(name, this.age, gender);
}

// [apply : 인자를 배열로 받음]
printYourself.apply(you, ['JK', 'male']); 
// JK 25 man

// [call : 인자를 그냥 받음]
printYourself.call(you, 'NJ', 'male'); 
// NJ 25 man

// [bind : 함수를 한 번 더 호출함]
printYourself.bind(you,'Hyun','female').call(); 
// Hyun 25 female

Reference

sjk5766님의 medium

wlsdnd2194님의 velog

MDN : this

0개의 댓글