Skip to content

Latest commit

 

History

History
210 lines (146 loc) · 5.33 KB

(10.9)this.md

File metadata and controls

210 lines (146 loc) · 5.33 KB

this

  • 자바스크립트의 함수는 호출 될 때 매개변수로 전달되는 인자 값 이외에 아래의 것을 전달받는다.
    • arguments 객체
    • this

함수 호출 패턴과 this 바인딩

1. 함수 호출 패턴
2. 메소드 호출 패턴
3. 생성자 호출 패턴
4. apply 호출 패턴

함수 호출 패턴

  • 전역객체는 모든 객체의 유일한 최상위 객체를 의미

    • Browser 에서는 window
    • Server 에서는 global
  • 전역객체는 전역 스코프를 갖는 전역변수를 프로퍼티로 소유

  • 전역 영역에 선언한 함수는 전역객체의 프로퍼티로 접근할 수 있다.


function foo() {
	console.log('test!');
}

window.foo();

  • this는 기본적으로 전역객체에 바인딩 된다.(즉, browser에서는 window)

function foo() {
  console.log("foo's this: ",  this); 
  function bar() {
    console.log("bar's this: ", this);
  }
  bar();
}
foo();

  • 메소드에서 this는 메소드를 가지고 있는 객체를 가르킨다.
  • 메소드의 내부함수일 경우에는 전역객체에 바인딩 된다.
  • 콜백함수의 경우에도 전역객체( ex : setTimeout)

메소드의 내부함수 전역객체 회피 방법

var value = 1;

var obj = {
  value: 100,
  foo: function() {
    var that = this;
    console.log("foo's this: ",  this);
    console.log("foo's this.value: ",  this.value); 
    function bar() {
      console.log("bar's this: ",  this);
      console.log("bar's this.value: ", this.value);

      console.log("bar's that: ",  that);
      console.log("bar's that.value: ", that.value);
    }
    bar();
  }
};

obj.foo();

메소드 호출 패턴

  • 함수가 객체의 프로퍼티이면 메소드 호출 패턴으로 호출 된다.
  • 즉 메소드에서의 this는 해당 메소드를 포함하고 있는 객체에 바인딩 된다.
  • 프로토타입 객체도 메소드를 가질 수 있다.

생성자 호출 패턴

  • 기존 함수에 new 연산자를 붙여서 호출하면 해당 함수는 생성자 함수로 동작
  • 생성자 함수로 만들어진 함수가 일반 함수처럼 사용될 수 있기 때문에 생성자 함수명은 첫문자를 대문자로 기술하여 혼란을 방지하려는 노력을 하는 것이 좋다.

생성자 함수 동작 방식

  1. 빈 객체 생성 및 this 바인딩
    1. 함수가 실행되기전에 빈 객체가 생성된다.
    2. 함수 내에서 this는 이 빈객체를 가르킨다.
  2. this를 통한 프로퍼티 생성
    1. 새로 생성한 프로퍼티와 메소드가 this 객체(빈객체)에 추가(즉, 구문들이 객체에 편입되어짐)
  3. 생성 된 객체 반환
    • 생성자 함수로 반환문이 없을 경우 this 객체가 반환된다.
var Person = function(name) {
  // 생성자 함수 코드 실행 전 -------- 1
  this.name = name;  // --------- 2
  // 생성된 함수 반환 -------------- 3
}

객체 리터럴 방식과 생성자 함수 방식의 차이


// 객체 리터럴 방식
var foo = {
  name: 'foo',
  gender: 'male'
}

console.dir(foo);

// 생성자 함수 방식
var Person = function(name, gender) {
  this.name = name;
  this.gender = gender;
}

var me  = new Person('Lee', 'male');
console.dir(me);

var you = new Person('Kim', 'female');
console.dir(you);

  • 객체 리터럴 방식과 생성자 함수 방식의 차이는 프로토타입 객체이다.
    • 객체 리터럴 방식의 경우 프로토타입 객체 : Object.prototype
    • 생성자 함수 방식의 경우 생성된 프로토타입의 객체 : Person.prototype

생성자 함수에 new 연산자를 붙이지 않고 호출할 경우

  • new가 없으면 일반 함수로 도앚ㄱ
  • this를 이용해 값을 할당하면 전역객체 window에 프로퍼티 생성후 값을 할당
  • 일반 함수는 반환문(return)이 자동으로 이루어지지 않으므로 return 값이 undefined이다.

apply 호출 패턴

  • 함수 호출 시 상황에 따라 this에 바인딩 될 객체를 결정
  • 자바스크립트 엔진 내부에서 자동으로 실시
func.apply(thisArg, [argsArray])

// thisArg: 함수 내부의 this에 바인딩할 객체
// argsArray: 함수에 전달할 인자 배열

var Person = function (name1, name2) {
  this.name1 = name1;
  this.name2 = name2;
};

var foo = {};

// apply 메소드는 생성자함수 Person을 호출한다. 이때 this에 객체 foo를 바인딩한다.
Person.apply(foo, ['kim', 'je']);

console.log(foo); // { name: 'name' }
  • apply의 대표적인 용도는 arguments와 같은 유사배열 객체에 메소드를 사용하는 경우
    • var arr = Array.prototype.slice.apply(arguments);
  • call() 메소드의 경우 apply와 기능은 같지만 인자를 넘기는 형태가 다르다.

Person.apply(foo, [1, 2, 3]);

Person.call(foo, 1, 2, 3);

  • apply 함수와 call 함수는 콜백함수의 this를 위해서 사용되기도 함.

function Person(name) {
  this.name = name;
}

Person.prototype.doSomething = function(callback) {
  if(typeof callback == 'function') {
    callback.call(this);
  }
};

function foo() {
  console.log(this.name);
}

var p = new Person('Lee');
p.doSomething(foo);  // 'Lee'

  • callback()으로 호출하면 p.doSomething(foo); 가 undefined를 나타냄
    • foo() 안의 구문 this가 window를 가르키기 때문.
  • callback.call(this)로 호출하면 this가 객체 p를 가르킴