This 와 바인딩

박선우·2023년 1월 16일
0

CS 스터디

목록 보기
17/53
post-thumbnail

🌼 This 와 바인딩

1️⃣ This binding

  • Object를 참조하는 keyword
  • javascript는 함수 호출 방식에 따라 '동적'으로 결정 된다.

2️⃣ 함수가 호출되는 방식

🐶 함수 호출시

  • 함수를 호출하면 해당 함수 내부 코드에서 사용된 this는 전역객체(window)에 바인딩된다.
  • 함수는 전역객체의 메소드이다. 따라서 메소드 호출시와 동일하게 메소드 객체(winodw)를 this로 갖는다.

🐶 메소드 호출시

  • 객체의 메소드를 호출할 때는 해당 메소드를 호출한 객체로 바인딩된다.
function Person(name) {
  this.name = name;
}

Person.prototype.getName = function() {
  return this.name;
};

var song = new Person("song");
song.getName(); //"song"
// this는 메소드를 호출한 객체인 song객체이다. 따라서 song.name인 “song”이 리턴된다.

Person.prototype.name = "kim";
Person.prototype.getName(); // "kim"
// this는 마찬가지로 메소드를 호출한 객체인 Person.prototype객체이다.따라서 “kim”이 리턴된다.

🐶 엄격모드에서의 this

  • 엄격 모드에서 함수 실행시 this는 undefined가 된다.
  • 내부 함수 호출시 this 또한 undefined가 된다.
  • 의도치 않게 전역객체에 바인딩된 this를 사용하는 것을 막을 수 있다.

🐶 이벤트 리스너 호출시 this

  • 객체의 메서드를 이벤트리스너로 등록했을 때에 this는 이벤트 객체이다.
#("btn").click(function(){
    console.log(this); // this는 #btn
})
  • 객체로부터 메소드가 분리되었을 때 this는 메소드가 정의된 객체가 아니다.
function Person(name) {
  this.name = name;
}

Person.prototype.getName = function() {
  return console.log(this.name);
};

var song = new Person("song");
song.getName(); //"song"

setTimeout(song.getName, 1000); //""
//"song"
  • 매개변수로 전달되었기 때문에 메소드는 객체로 부터 분리되어 있고, 함수로써 실행이 된다.

메서드가 정의된 객체를 this로 바인딩하기 위해서는 apply, call, bind를 사용해야한다.

🐶 생성자 함수 호출시 this

  • 자바스크립트 생성자 함수는 객체를 생성한다. 가존 함수에 new를 붙여서 호출하면 생성자 함수로 동작한다.

⓵ 빈 객체 생성 및 this 바인딩

  • 빈 객체 -> 생성된 객체는 this로 바인딩 -> 생성자 함수 코트 내부 this는 빈 객체 -> 이 빈객체가 생성자 함수가 새로 생성하는 객체

② this를 통한 프로퍼티 설정

  • 생성된 빈 객체에 this를 사용해 동적 프로퍼티, 메소드를 생성할 수 있다.

③ 생성된 객체 리턴

  • 정의된 return문이 없다면 새로 생성된 객체가 return
  • 다른 객체를 return하게 했다면 다른 객체가 return
  • 객체가 아닌 값을 return 하는 경우, this로 바인딩된 새 객체가 리턴
var Person = function(name) {
  // 1. 빈 객체 생성 및 this 바인딩
  this.name = name; //2. this를 통한 프로퍼티 설정
  // 3. 생성된 객체 리턴
};
var song = new Person("song");
console.log(song.name);

  • new를 쓰지 않고 객체를 생성하려할 때, 전역객체에 프로퍼티가 할당되는 등 문제가 생길 수 있다. 그러함으로, new를 통해 생성하도록 강제해준다.
var Person = function(name) {
  if (!(this instanceof arguments.callee)) {
    return new arguments.callee(arg);
  }
  this.name = name;
};

🐶 Arrow 함수 호출시 this

  • Arrow함수를 선언할 때 this에 바인딩될 객체가 정적으로 결정된다.
  • Arrow 함수의 this는 언제나 상위 스코프의 this를 가리킨다.

③ 객체의 메소드를 Arrow 함수로 정의하는 경우

  • 상위 스코프의 this인 전역객체가 this가 된다.
const song = {
  name: "song",
  // ES6의 축약 메소드 표현을 사용해야 한다.
  sayHi() {
    // === sayHi: function() { 1
    console.log(`Hi ${this.name}`); // 2
  }
  
};

song.sayHi(); // 1. Hi undefined
song.sayHi(); // 2. Hi

call, apply, bind를 이용한 this 바인딩

⓵ call

  • fun.call(thisArg[, arg1[, arg2[, …]]])
  • thisArg : 지정할 this
  • arg1 … : 객체를 위한 인수
function greet() {
  var reply = [this.animal, "typically sleep between", this.sleepDuration].join(" ");
  console.log(reply);
}

var obj = {
  animal: "cats",
  sleepDuration: "12 and 16 hours"
};

greet.call(obj); // cats typically sleep between 12 and 16 hours

② apply

  • function.apply(thisArg, [argsArray])
  • thisArg : 지정할 this
  • argsArray : 유사배열 객체(arguments)
  • apply가 두 번째 인자를 배열로 넘긴다는 차이가 있다.

③ bind

  • bind를 사용하면 this 값을 영구히 바꿀 수 있다.
function greet() {
  console.log(`Hello, I'm ${this.name}`);
}
greet(); //Hello, I'm
const songGreeting = greet.bind({ name: "song" });
songGreeting(); // Hello, I'm song;
profile
코린이 열심히 배우자!

0개의 댓글