Search
Duplicate

this

1. this개요, this와 글로벌 오브젝트, this와 window오브젝트

this개요

키워드
obj.name()형태로 호출한 함수(메소드)에서this로 인스턴스(오브젝트)를 참조 합니다.
실행 콘텍스트의this 바인딩 컴포넌트에 바인딩됩니다.

this와 글로벌 오브젝트

글로벌 오브젝트에서 this는 글로벌 오브젝트를 참조합니다.
this와 window 오브젝트에서 window는 JS에서 만든것이 아니고 글로벌 오브젝트의 스코프도 아닙니다.
window와 글로벌 오브젝트를 같은 선상에서 사용합니다. 이는 Host 오브젝트 개념을 적용하기 때문입니다.
글로벌 오브젝트에 코드를 작성해봅니다.
⇒ window.onload = function(){//안이 아니라 밖에 코드 작성};
this가 window 참조
console.log(this === window);//true
JavaScript
복사
this로 글로벌 변수 사용
var value = 100; console.log(this.value);//100
JavaScript
복사
window로 글로벌 변수 사용
var value = 100; console.log(window.value);//100
JavaScript
복사
this.value = 100;형태로 값 할당
⇒ window 오브젝트와 같이 다른 오브젝트를 마치 내것 처럼 사용하는 개념을 Host 오브젝트라고 합니다. DOM오브젝트도 Host 오브젝트입니다.
this.value = 100; console.log(window.value);//100
JavaScript
복사

this와 window 오브젝트

window.onload = function() { //여기에 코드 작성 };
this가 window 참조
⇒onload 이벤트가 발생하면 실행 컨텍스트를 만들게 되고 this 바인딩 컴포넌트에 window가 할당되면서 this === window가 true를 반환합니다.
window.onload = function(){ console.log(this === window);//true };
JavaScript
복사
this로 로컬(지역)변수 사용
⇒ var value에서 value는 핸들러 함수의 지역변수입니다. 근데 this는 window 오브젝트를 참조하기에 this.value로 지역 변수에 액세스 할 수 없습니다.
window.onload = function(){ var value = 100; console.log(this.value);//undefined };
JavaScript
복사
this.value = 100;형태로 값 할당
⇒ this가 window 오브젝트를 참조하기에 window 오브젝트에 value가 할당되고 100이 출력가능해집니다.
window.onload = function(){ this.value = 100; console.log(window.value);//100 };
JavaScript
복사

2. this참조 범위, this와 strict모드, this참조 오브젝트

this와 strict 모드

오브젝트.함수이름() 형태로 함수 호출
글로벌 오브젝트는 오브젝트 이름이 없기에 함수 이름만 작성하여 호출합니다.
strict 모드에서는 window.book()처럼 book()앞에 window를 글로벌 오브젝트로 작성합니다.
함수 앞에 오브젝트를 작성하지 않으면 this 바인딩 컴포넌트에 undefined가 설정되기에 this로 window를 참조할 수 없습니다.
function book(){ "use strict"; return this; }; var result = book(); console.log(result);//undefined
JavaScript
복사
⇒ 호출하는 book()함수 앞에 오브젝트를 작성하지 않으면 return this에서 undefined를 반환하는데 이는 this 바인딩 컴포넌트에 undefined가 설정된다는 의미입니다.
function book(){ "use strict"; return this; }; var result = window.book(); console.log(result===window);//true
JavaScript
복사
⇒ 호출하는 book() 함수 앞에 window 오브젝트를 작성하면 book 함수가 글로벌 함스이므로 호출되며 return this에서 window오브젝트를 반환합니다.

this 참조 오브젝트

var book = { point: 100, member: { point: 200, get: function(){ console.log(this === book.member); console.log(this.point); } } }; book.member.get();
JavaScript
복사
this가 참조하는 오브젝트
마지막 줄에서 book.member.get() 호출
this가 member 오브젝트를 참조합니다.
book은 get()을 호출하는 경로 역할
console.lolg(this === book.member);
실행결과로 true가 출력되며 this가 book.member를 참조하기 때문입니다.
즉, this바인딩 컴포넌트에 book.member 오브젝트가 설정됩니다.
console.log(this.point);
this가 book.member를 참조하기에 book.point값인 100을 출력하지 않고 book.member의 200을 출력합니다.

3. this와 인스턴스

this와 인스턴스

인스턴스의 목적
인스턴스마다 고유 값을 유지합니다.
function Book(point){ this.point = point }; Book.prototype.getPoint(){ console.log(this.point); } var obj1 = new Book(100); var obj2 = new Book(200); obj1.getPoint();//100 obj2.getPoint();//200
JavaScript
복사
인스턴스에서 this의 목적
this로 인스턴스를 참조하여 this.name형태로 프로퍼티에 접근할 수 있습니다.
__proto__ 프로퍼티 접근
prototype에 연결된 프로퍼티가 인스턴스의 __proto__에 첨부되며 this.method()형태로__proto__에 첨부된 method()호출이 가능합니다.

코드를 통해 분석

var book = {}; book.Point = function(point){ this.point = point; }; book.Point.prototype.getPoint = function(){ console.log(this.point); }; var obj = new book.Point(100); obj.getPoint();//100
JavaScript
복사
1.
var obj = new book.Point(100);
book.Point 인스턴스를 생성합니다.
2.
this.point = point;
this가 생성한 인스턴스를 참조하므로 point는 인스턴스 프로퍼티가 됩니다.
이 논리로 인스턴스마다 프로퍼티 이름과 값을 유지할 수 있습니다.
3.
obj.getPoint();
obj 인스턴스의 getPoint() 메소드 호출
4.
console.log(this.point);
obj.getPoint()로 호출, this가 obj참조
obj는 book.point 인스턴스
book.point인스턴스의 point값 출력

4. this와 call()메소드, this사용, Object사용, 숫자 작성, this참조 변경

this와 call()

getTotal.call(this, 10, 20)
10과 20을 파라미터 값으로 넘겨줍니다.
첫 번째는 파라미터 값으로 넘어가지 않고 두 번째부터 넘어갑니다.
첫 번째 파라미터에 호출된 함수에서 this로 참조할 오브젝트를 작성 하는데 this이외에 다른 오브젝트도 사용이 가능합니다.

this사용

1.
get.call(this, 20)
첫 번째 파라미터에 this 작성
2.
return param + this.value;
this가 글로벌 오브젝트를 참조하므로 var value = 100을 사용합니다.
만일, call()을 사용하지 않고 get함수를 호출한다면 return param + this.value는 get(20)으로 호출하면 this가 undefined를 참조하므로 에러가 발생합니다.
"use strict" var value = 100; function get(param){ return param + this.value; }; var result = get.call(this, 20); console.log(result);
JavaScript
복사

Object 사용

1.
var result = get.call(value, 50);
call()의 첫 번째에 Object를 작성해줍니다.
50은 파라미터 값입니다.
2.
return this.base * this.rate + value;
this가 {base: 20, rate:30}을 참조합니다
20 * 30 + 50이 됩니다.
3.
this로 참조할 오브젝트를 변경할 수 있는 것이 call()의 특징입니다
var get = function(value){ return this.base * this.rate + value; }; var value = {base: 20, rate: 30}; var result = get.call(value, 50); console.log(result);//650
JavaScript
복사

숫자 사용

1.
var result = get.call(123);
this가 오브젝트를 참조하므로 숫자(123)를 작성하면 에러가 발생하는게 맞습니다. 하지만 실제 동작을 시키면 에러가 나지 않습니다.
그 이유는 값 타입에 해당하는 Number 인스턴스를 생성후 123을 primitive 값으로 설정하여 this는 Number(123)을 참조하기 때문입니다.
function get(){ return this.valueOf(); }; var result = get.call(123); console.log(result);//123
JavaScript
복사

this참조 변경

1.
book.point.get.call(book);
book.point의 get()호출
get()에서 this로 book 오브젝트를 참조합니다.
this.value는 book.value이기에 123을 출력합니다.
2.
book.point.get.call(book.point);
book.point의 get() 호출
get()에서 this로 book.point오브젝트를 참조합니다.
this.value가 book.point.value이기에 456을 출력합니다.
var book = { value: 123, point: { value: 456, get: function(){ console.log(this.value); } } }; book.point.get.call(book); book.point.get.call(book.point);
JavaScript
복사

5. this와 apply()메소드, this와 arguments

this 바인딩 컴포넌트와, 파라미터를 유동적으로 변경하며 로직을 수행하기위해 사용하는 함수

this와 apply()

getTotal.apply(this, [10,20])
함수 호출 방법은 call()과 동일하며 파라미터가 배열인 것이 차이점입니다.
[10,20]을 파라미터 값으로 넘겨줍니다.
두 번째 파라미터 수가 유동적일 때 사용합니다.
call()은 파라미터 수가 고정을 때 사용합니다.

this와 arguments

1.
get.apply(obj, data);
get()함수에서 obj를 this로 참조합니다.
2.
두 번째 파라미터 [4,5,6]을 arguments를 사용하여 계산합니다.
파라미터 수가 유동적이므로 arguments가 편리합니다.
3.
get()의 함수 코드는 바뀌지 않으며 넘겨주는 파라미터 값과 this로 참조할 오브젝트만 변경하면 됩니다.
4.
Array-like 형태입니다.
var obj = {0: 10, 1: 20, 2: 30}; var data = [4, 5, 6]; function get(){ for(k = 0; k < arguments.length; k++){ console.log(arguments[k] + this[k]); }; }; get.apply(obj,data);
JavaScript
복사
[실행 결과]
14
25
36

6. this와 콜백 함수

this와 콜백 함수

1.
ES5의 map(), forEach()처럼 콜백 함수가 있는 메소드는 두 번째 파라미터에 this로 참조할 오브젝트를 작성(optional)
2.
function callback(element, index, data){ return element + this.value; };
map()에서 호출하는 콜백 함수
3.
return data.map(callback, obj);
mpa()의 두 번째 파라미터에 obj를 작성합니다.(this 바인딩 컴포넌트)
callback()에서 obj를 this로 참조합니다.
4.
map()의 코드는 바꾸지 않고 obj와 data파라미터 값만 바꾸면 됩니다.
var obj = {value: 100}; var data = [5, 6, 7]; function callback(element, index, data){ return element + this.value; }; function get(data){ return data.map(callback, obj); }; var result = get(data); console.log(result);
JavaScript
복사
[실행 결과]
[105, 106, 107]

7. this와 bind()메소드, function 오브젝트 생성/호출 파라미터 병합

bind()

bind메소드는 '무엇을' 묶는것인가에 대해 생각해 볼 필요가 있습니다. 일반적으로 함수는 호출즉시 실행하지만, bind()메소드는 function 오브젝트를 만드는 것과 생성한 function 오베즉트를 함수로 호출하는 2 단계가 존재합니다.
파라미터
1번째 파라미터에 함수에서 thi로 참조할 오브젝트를 작성합니다.
2번째 파라미터에 호출된 함수의 파라미터 값을 작성합니다.
생성한 function을 호출할 때에도 파라미터 작성이 가능합니다.
두 개의 파라미터를 병합하여 사용합니다.

function 오브젝트 생성, 호출

1.
var obj = book.get.bind(book);
book.get()을 호출하지 않고 function 오브젝트를 생성하여 반환합니다.
생성한 function 오브젝트를 생성한 오브젝트의 [[TargetFunction]]에 설정합니다.
처리를 나누어 하기에 저장이 필요합니다.
2.
console.log(typeof obj);
obj의 타입은 function 오브젝트입니다.
3.
bind()의 첫 번째 파라미터
get() 함수에서 this로 참조할 오브젝트를 작성합니다.
get() 앞에 작성한 오브젝트를 this로 참조하지 않습니다(book)
작성하지 않으면 undefined로 설정됩니다.
생성한 function 오브젝트의 [[BoundThis]]에 설정됩니다.
var book = { point: 123, get: function(){ return this.point; } }; var obj = book.get.bind(book); console.log(typeof obj); var result = obj(); console.log(result);
JavaScript
복사
[실행 결과]
function
123

파라미터 병합

var obj = book.get.bind(this, 10, 20);
두 번째, 세 번째 파라미터에 값을 작성했으며 book.get()의 파라미터 값으로 넘겨줍니다.
function 오브젝트의 [[BoundArguments]]에 설정됩니다.
get()함수에 파라미터 이름을 작성하지 않고 arguments를 사용합니다.
return Array.prototype.slice.call(arguments);
slice()는 인덱스 범위의 엘리먼트를 배열로 반환합니다.
인덱스를 작성하지 않으면 arguments전체를 반환합니다.
var result = obj(30, 40)
book.get()함수가 호출되며 book.get.bind(this, 10, 20);에서 10과 20을 [10,20]형태로 반환합니다
var book = { get: function(){ return Array.prototype.slice.call(arguments); } }; var obj = book.get.bind(this, 10, 20); var result = obj(30, 40); console.log(result);
JavaScript
복사

8. bind()활용, 이벤트 처리

bind()활용, 이벤트 처리

예제
"값 출력" 버튼 클릭시 값을 표시합니다.
이벤트 처리의 어려움은
이벤트를 설정할 때의 오브젝트를 핸들러에서 this로 참조 할 수 없다는 것
bind()로 해결할 수 있습니다.
document.getElementById("point");
button#point로 엘리먼트 오브젝트 생성
node.onclick = this.show.bind(book,node);
show()는 onclick 이벤트의 핸들러
<script src="point.js" defer></script> <button id="point">값 출력</button>
HTML
복사
var book = { myPoint: 100, setEvent: function(){ var node = document.getElementById("point"); node.onclick = this.show.bind(book, node); }, show: function(node, event){ console.log(node.textContent); console.log(this.myPoint); } }; book.setEvent()
JavaScript
복사