this : 실행 컨텍스트가 생성될 때 결정 = 함수를 호출할때 결정된다.
전역공간에서
var a = 1;
console.log(a); //1 (window.)생략된것이라고 여기자
console.log(window.a); //1
console.log(this.a) //1
함수 호출시
그 자체로 독립적인 기능 수행
함수에서의 this는 전역객체를 가리킵니다.
설계상의 오류?!😂
var func = function(x){
console.log(this, x);
};
func(1); //window { ... } 1 > 함수로 오출한것.
var obj = {
method: func
};
obj.method(2); // { method: f } 2 > 메서드로서 호출한 것.
점 표기법, 대괄호 표기법이던, 호출할때 함수 이름 앞에 객체가 명시되어 있는 경우에는 메서드로 호출한 것, 그렇지 않은 모든 경우에는 함수로 호출한 것.
var obj = {
method: function(x) {console.log(this, x); }
};
obj.method(1); //{ method: [Function: method] } 1 =
obj['method'](2); //{ method: [Function: method] } 2
var obj1 = {
outer: function() {
console.log(this); //(1) obj1
var innerFunc = function() {
console.log(this); //(2)window(전역객체) (3)obj2
}
innerFunc(); //함수로서 호출 -> this지정 x -> 전역객체 window 바인딩
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod(); //메서드로서 호출 this -> .앞 객체 obj2가 바인딩
}
};
obj1.outer(); //메서드로서 호출 -> .앞 객체 obj1가 바인딩
7번째와 12번째 줄.. 같은 함수임에도 바인딩되는 this의 대상이 서로 다르다!!
⇒ this바인딩에서는 오직 해당 함수를 호출하는 구문앞에 점 또는 대괄호 표기가 있는지 없는지가 관건이다.
var obj = {
outer : function() {
console.log(this);
var innerFunc1 = function() {
console.log(this);
};
innerFunc1(); //내부 this는 window를 가리킴..
var self = this;
var innerFunc2 = function () {
console.log(self);
};
innerFunc2();
}
};
obj.outer();
innerFunc1 내부에서는 this전역객체를 가리킨다.
한편 outer 스코프에서 self라는 변수에 this를 저장한 상태에서 호출한 innerFunc2의 경우 self에는 객체 obj가 출력된다.
var self = this;
를 통해서 상위 스코프의 this를 저장해 내부함수에서 사용
var obj = {
outer: function() {
console.log(this); //(1) { outer : f }
var innerFunc = () => {
console.log(this); //(2) { outer :f }
};
innerFunc();
}
};
obj.outer();
메서드 호출시
var obj = {
methodA: function() {console.log(this); },
inner: {
methodB: function() {console.log(this);}
}
};
obj.methodA(); //methodA: [Function: methodA],
//inner: { methodB: [Function: methodB] }
obj['methodA'](); //위와 동일
obj.inner.methodB(); //{ methodB: [Function: methodB] }
obj.inner['methodB'](); //{ methodB: [Function: methodB] }
obj['inner'].methodB(); //{ methodB: [Function: methodB] }
obj['inner']['methodB'](); //{ methodB: [Function: methodB] }
setTimeout(function() { console.log(this); }, 300);
[1, 2, 3, 4, 5].forEach(function (x) {
console.log(this, x);
});
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function(e) {
console.log(this, e);
});
var callback = function() {
console.dir(this); //window
};
var obj = {
a: 1,
b: function(cb) {
cb();
}
};
obj.b(callback);
var callback = function() {
console.dir(this); //obj
};
var obj = {
a: 1,
b: function(cb) {
cb.call(this);
}
};
obj.b(callback);
cb를 그냥 호출하지 않고 this 인자를 넘겨줌
cb의 this는 obj이므로 ⇒ obj
⇒ 콜백이라는 함수를 처리할때 this를 obj라고 해라라는 명령이 있으면 ⇒ obj
그렇지 않으면 전역객체(window)가 나온다. (기본적으로는 전역 객체)
function a () {
var argv = Array.protorype.slice.call(arguments);
argv.forEach(function (arg) {
console.log(arg);
});
}
a(1,2,3);
document.body.innerHTML = '<div>a</div><div>b</div><div>c</div>';
var nodeList = document.querySelectorAll('div');
var nodeArr = Array.prototype.slice.call(nodeList);
nodeArr.forEach(function (node) {
console.log(node);
});
call, apply, bind 메소드