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
복사