-
오늘은 this를 공부했다. 증말 어렵다.
var a = 10; var obj = { a: 20, b: function() { console.log(this.a);
아래에서 메소드로 불러왔기 때문에 20 출력
function c() { console.log(this.a); } c(); }} obj.b();
이상하지만 함수로 호출했기 때문에 a=10이 나온다
- 이걸 우회하는 방법은?
// this를 변수에 담으면 된다!
var a = 10; var obj = { a: 20, b: function() { var self = this; console.log(this.a); function c() { console.log(self.a);} c(); } } obj.b();
함수로 호출했지만 this를 찾지 않고, 실행 컨텍스트 내부의 self를 찾게끔 한것.
c에서는 self가 없으니 외부 컨텍스트에서 찾는다
// callback으로 호출시엔 기본적으로 함수내부에서와 동일하다
// 그전에 call, apply, bind 메소드를 먼저 알아보자
// bind는 변수에다가 실행한 결과를 담는다
function a(x,y,z) {
console.log(this,x,y,z);
}
var b = {
c: 'eee'
};
a.call(b,1,2,3);
// a를 호출할건데, this는 b로, 인자로는 각각 1,2,3으로 호출해!
a.apply(b,[1,2,3]);
// a를 호출할건데, 요런 애들을 적용할거야. this는 b고, 두번째인자로는 배열을 넣고 실행해!
var c = a.bind(b);
//이건 호출하는게 아니다! 새로운 함수를 만드는 것. 그 새로운 함수는, this가 b였으면 좋겠어.
c(1,2,3);
var d = a.bind(b,1,2);
// 새로운 함수를 만들건데, this는 b, 첫번째 인자 두번째인자까지는 각각 1과 2를 넣을게. 나머지를 지정하면 그때 실행해.
d(3);
// 결과는 모두 동일! => Object {c:"eee"} 1 2 3
// 그렇게 담겨있는 c를 가지고 1,2,3을 넘겼더니 this가 b로 나왔다
// 1. bind를 했을 때 b를 넘겨서 this가 b가 됐고
// 2. 인자로 1,2,3 넘기면서 실행이 됨
// this가 b를 가리키는 새로운 함수를 c에다 담은것이다
// 인자가 this,x,y까지는 있는 상태에서 다음 인자를 기다리는 함수 d를 만든 것
// 그러니까 3만 넘겨주면 들고있던 this,x,y와 함께 z에 3을 넣고 실행한다
/*
function.call(thisArg[,arg1[,arg2[, ...]]]) => 즉시호출
function.apply(thisArg, [argsArray]) => 즉시호출
function.bind(thisArg[,arg1[,arg2[, ... ]]]) => 새로운 함수 생성!!!
실행할 때 thisArg로 지정해라
*/
// [ 대괄호가 있는 애들은 생략할 수 있는 애들, 없으면 생략할 수 없는애들
var callback = function() {
console.dir(this); // => 전역객체 window 출력!
};
var obj = {
a: 1,
b:function(cb) {
cb();
}
};
obj.b(callback);
//obj.b를 실행하는데 인자로 callback을 넘겨라
// 그럼 obj.b를 찾아가자. obj.b는 메소드로써 저 함수를 실행하는거다.
// 그럼 function(cb) < 이 인자 cb의 자리에 callback이 들어가겠지
// callback을 출력했더니, 그건 또 함수야. this를 출력하라는 함수.
// 1. obj.b를 호출했으니까 여기서의 this는 obj인데,
// 2. 그 안에서 다시 cd를 호출했어. cd의 this는 전역객체
// => 호출한 그것만 보면 된다
// 그런데 이렇게 하면?
var callback = function() {
console.dir(this); // => obj 출력!
};
var obj = {
a: 1,
b:function(cb) {
cb.call(this); //cb를 그냥 부른게 아니라 this를 인자로 넘겼어.
// b라고 하는 실행 컨텍스트 내부의 this는 obj다.
}
};
obj.b(callback);
//여기서 callback을 가지고 this를 내가 가지고 있는 this로 하겠다고 지정을 해버렸기때문에 cd.call(this)가 obj됨.
var callback = function() {
console.dir(this); // => window 출력
};
var obj = {
a: 1
};
setTimeout(callback,100);
// 100ms 뒤에 callback을 실행해라.
// setTimeOut에서는 this 처리를 별도로 하지 않고 있기 때문에!
// 근데 이걸
var callback = function() {
console.dir(this); // => obj 출력
};
var obj = {
a: 1
};
setTimeout(callback.bind(obj),100);
// 이렇게 bind를 하면 우선순위가 먹힌다
decodeURIComponent.body.innerHTML += '<div id="a"클릭하세요</div>';
document.getElementById('a').addEventListener('click',function() {
console.dir(this); // => div#a 출력
})
// addEventListener가 callback함수를 처리할 때, this를 이벤트가 일어난 그 대상 타겟으로 정하게끔 정의되어있기 때문에
function Person(n,a) {
this.name = n;
this.age = a;
}
var gomugom = new Person('고무곰',30); //생성자 함수로 객체를 만들었으니 객체자체가 this가 돼서
// 객체.name에 고무곰, 객체.age에 a 가 들어간 채로, 그 만들어진 객체가 gomugom이라는 변수에 담긴다
console.log(gomugom); //새로 생성된 인스턴스 자체가 this가 된다.
'JS' 카테고리의 다른 글
클로저 closer (0) 2021.08.12 callback (0) 2021.08.10 this (0) 2021.08.08 Execution Context (0) 2021.08.07 Data type (0) 2021.08.06