JavaScript - this에 대해 알아보자

Sonny·2019년 10월 15일
0

JavaScript

목록 보기
16/29
post-thumbnail

this

javascript에서의 this라는 키워드는 거의 모든 상황에서 객체이며 문법적으로는 '나'와는 단어와 비슷하다. this의 값은 this를 사용하는 해당 함수를 어떻게 실행하느냐에 따라 값(의미)이 바뀐다.

this를 실행하는 방식

this는 크게 4가지 방식으로 실행을 하며 각각의 방식에 따라 가리키는 주체가 달라진다.

1. Regular function call - 일반 함수 실행 방식

1.1 strict mode가 아닌 경우

function foo () {
  console.log(this.name); // 'this' === global object (브라우저상에선 window 객체)
}

foo();

일반 함수 방식이란 위와 같이 일반적으로 함수를 실행하는 가장 기본적인 방식이다. 이 방식에서 this는 global object (브라우저상에선 window 객체)이다.

1.2 strict mode인 경우

'use strict';

var name = 'ken';

function foo () {
  console.log(this.name); // 'this' === undefined
}

foo();

strict mode에서 "this"는 undefined이다.
(개발자가 window를 가르키려고 this를 쓰지는 않기 때문)

1.3 일반 함수 실행 방식 예제

var age = 100;

function foo () {
  var age = 99;
  bar(age);
}

function bar (age) {
  console.log(this.age); // 100
}

foo();

위 함수에서 99가 실행이 될것 같지만 bar()라는 함수가 실행되는 부분에서 일반함수 실행방식으로 실행시켰기때문에 thiswindow가 되었고 window.age는 100이기 때문에 100이 실행되었다.

2. Dot Notation - 점 방식

오브젝트 메소드 형식으로 실행시키는 방식

2.1 Dot Notation 예제

var age = 100;

var ken = {
  age: 35,
  foo: function foo () {
    console.log(this.age); // 35
  }
};

ken.foo();

this함수를 호출할때 함수 앞에 .을 사용하여 메소드를 실행시킬 경우, this는 .앞의 객체가 this의 값으로 설정이 된다.

2.2 Dot Notation 예제

function foo () {
  console.log(this.age);
}
var age = 100;
var ken = {
  age: 36,
  foo: foo
};
var wan = {
  age: 32,
  foo: foo
};
ken.foo(); // 36
wan.foo(); // 32

그냥 foo()를 실행을하게되면 100이 출력되겠지만 dot nation방식으로 실행을 하기 때문에 this가 가리키는 값이 .앞의 객체로 바뀐다.

2.3 Dot Notation 예제

var age = 100;
var ken = {
  age: 35,
  foo: function bar () {
    console.log(this.age);
  }
};
var wan = {
  age: 31,
  foo: ken.foo
};
var foo = ken.foo;
ken.foo();  // 35
wan.foo();  // 31
foo(); // what is the value of 'this' in this case?  // 100

ken.foo : ken이라는 객체안의 메소드지만 결국 bar라는 함수이다.
객체안의 메소드지만 this의 방식에 따라 각각 다르게 호출이 된다.

3. Function.prototype.call, Function.prototype.bind, Function.prototype.apply - explicit binding (명시적 바인딩)

call, bind, apply와 같은 메소드들을 사용해서 함수를 실행하는 명시적 바인딩 방법

3.1 Explicit binding 예제

var age = 100;

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

var ken = {
  age: 35,
  log: foo
};

// foo function gets invoked
// `this` refers to first argument

foo.call(ken);

var kenLog = ken.log;

kenLog();
foo.call(ken); // ?
foo.apply(ken); // ?

foo.call(wan) : foo()라는 함수가 실행이 되는데 this의 값이 인자의 값으로 준 wan이 되어 실행이 된다.

foo.apply(ken) : foo()라는 함수 실행이 되고 ken이라는 인자값이 this의 값으로 설정이 되어 실행이 된다.

일반함수 실행 방식, dot Notaition 방식과 다르게 this의 값이 어떤 객체가 되어야 하는지 개발자가 직접 정하고 명령을 내릴 수 있다.

3.2 Explicit binding 예제

var age = 100;

function foo (a,b,c) {
  console.log(this.age);
  console.log(arguments);
}

var ken = {
  age: 35
};

foo.call(ken, 1, 2, 3, 4, 5);
foo.apply(ken, [ 1, 2, 3, 4, 5 ]);

foo.call(ken, 1, 2, 3, 4, 5); : 35, 1,2,3,4,5가 담겨있는 유사배열 출력
foo.apply(ken, [ 1, 2, 3, 4, 5 ]); : 인자가 여러개일 경우, 첫번째 인자가 this 값으로 설정이 되어 실행된다. 두번째 인자부터 나머지는 foo라는 함수의 인자값으로 넘어가게 된다.

foo aply() : call은 인자의 수가 정해져있지 않고 그냥 보내주면 됨
apply는 항상 인자를 두개만 받으며 두번째 인자는 무조건 배열이 되어야 하며 foo라는 함수 안에 인자로 각각 들어가게 된다.

3.3 Explicit binding 예제

var age = 100;
function foo () {
  console.log(this.age);
}
var ken = {
  age: 35,
  log: foo
};
var bar = foo.bind(ken);
var baz = foo;
bar(); // 이때 함수가 실행된다.

baz();

ken이라는 인자값을 넘겨주고 bind라는 메소드를 실행한 결과값을 bar라는 변수에 담는다.

bind라는 메소드는 모든 함수에 사용가능하며 첫번째 인자로 받는 kenthis값으로 설정됨 callbind와 다르게 해당 함수(foo)를 바로 실행시키지는 않는다. 하지만 foo라는 함수안의 this값을 ken으로 설정해놓은 함수를 반환해준다. (실행은 안됨)

3.4 Explicit binding 예제

var age = 100;
function foo () {
  console.log(this.age);
  console.log(arguments);
}
var ken = {
  age: 34
};
var bar = foo.bind(ken, 1, 2, 3);
bar(1,2,3,4,5);

4. 'new' keyword 방식

4.1 'new' keyword 예제

function Person () {
  console.log(this);
  this.age = 3333;
}

new Person();

this의 값을 판별하기 위해서는 foo라는 함수가 어떻게 실행되느냐를 찾아야한다. new라는 단어를 앞에 넣어 실행을 했다. 이럴 경우, this의 값은 빈 객체가 생성이 된다고 생각하면 된다. 빈 객체가 새롭게 생성돼서 함수속의 this값으로 할당이 되어 함수가 실행이 된다. ( 새로운 객체가 this값으로 들어간다.)

4.2 'new' keyword 예제

function Person () {
  // this = {};

  this.name = 'ken';

  // {
   // name : 'ken';
  // }
  
  // return this;
}

var ken = new Person();
console.log(ken);  // Person?{name: "ken"}

new Person() 하면 this는 새로운 객체가 된다.
Person함수 내부에는 그 빈 객체에 name이라는 keyken이라는 값을 할당해준다. Person에는 return이 없지만 new라는 단어를 사용하면 return을 해주지 않았지만 new를 사용하여 함수를 실행하게 되면 사용자가 쓰지 않아도 return this;가 자동으로 된다.

보통 new라는 키워드를 쓸 경우, return을 잘 쓰지 않는다.

4.3 'new' keyword 예제

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

var ken = new Person('ken');
console.log(ken);	// Person {name : 'ken'};

함수기때문에 마찬가지로 인자를 넣을 수 있다.

4.4 'new' keyword 예제 : Constructor function (생성자 함수)

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

// instances"라고 한다.
var ken = new Person('ken huh', 34);
var wan = new Person('wan huh', 30);

console.log(ken);  // Person?{name: "ken huh", age: 34}
console.log(wan);  // Person?{name: "wan huh", age: 30}

// 새로운 객체가 선택이 된다.

생성자함수는 보통 맨앞을 대문자로 해준다. new를 써서 함수를 실행시킬때마다 this에는 새로운 객체가 할당이 돼서 실행이 된다. 새로 만들어진 객체들은 instance라고 불려진다.

함수 호출되기까지의 과정과 이 4가지 상황을 많이 연습하면 this에 대해 완벽하게 이해할 수 있다.

참고사이트

profile
FrontEnd Developer

1개의 댓글

comment-user-thumbnail
2024년 1월 11일

Unlock your potential and elevate your cybersecurity expertise with the Fortinet https://www.dumpstool.com/NSE7_EFW-7-2-exam.html dumps [2023]. Designed to empower professionals like you, these meticulously crafted study materials offer a comprehensive insight into the latest advancements in Fortinet's cybersecurity solutions.

Immerse yourself in a wealth of knowledge covering essential topics such as advanced threat protection, secure SD-WAN, and network security. The NSE7_EFW-7.2 dumps provide a strategic approach to mastering Fortinet's technologies, ensuring you stay ahead in the ever-evolving cybersecurity landscape.

With real-world scenarios and practical exercises, these dumps not only prepare you for the NSE7_EFW-7.2 exam but also equip you with the skills needed to tackle today's cyber threats. Stay competitive and fortify your career with the industry-leading expertise gained from Fortinet's NSE7_EFW-7.2 dumps [2023]. Your journey to becoming a certified Fortinet professional starts here.

답글 달기