this
this 는 스코프를 가리키지않는다
상위 글로벌은 다 윈도우다
함수에서 this 는 인터프린터시점에 만들어지지않고 , 실행할때 만들어진다
함수안에서!!!! 함수 안에서다!
this 는 a.b.c.d() 이렇게 실행순서가 되어있다고 가정할때
쩜의 앞에 놈이 this 이다
이게 뭔말이냐면
어디서 실행했냐가 중요한것이다고, 어디서 실행시킨놈이 this이다
d()함수를 실행시킨놈은 c이다 그러므로 c가 this인 것이다
실행시킨 놈이 this이고 그게 바로 쩜 앞에 놈이란 말이다.
obj.a = cnosole.log(this) 이거는 this는 윕도우이다.
객체안에 들어가있다고해서 다른게 아니다
var obj = {
fn: function () {
console.log(this);
}
}
setTimeout(obj.fn , 100);
이거는 this가 뭐가 나올것같은가?
윈도우가 나온다 !
왜냐면
api 함수들을 쓰게되면 그 괄호안에 obj.fn 이렇게 넣는다고 해서 이게 실행이라는 뜻이아니다
obj.fn () 이렇게 되는게 실행을 하는거고,
저 셋타임아웃 함수인자로넘겨주는 괄호안에는 그냥 말그대로 넘겨주는 역할만 하는용도이다.
그래서 실제로 셋타임함수가 실행이 되는거지 저 obj.fn이 실행이되는게 아니기 떄문에 윈도우가 나오는거다
==============
var someone = {
name : 'codejong',
who : function() {
console.log(this);
}
};
someone.who(); // 이건 코드종이나온다
그러나
var mywho = someone.who;
mywho(); //이건 윈도우가 나온다
그리고
var btn = document.getElementById('btn');
btn.addEventListener('click', someone.who); // 이건 여기서 this는 버튼이 나온다 왜?
그냥 이벤트리스너 괄호안의 인자로 넘겨주는값이니까
그냥 값으로 넘겨줄뿐 실행은 되지않고 여기서 실행이 되는건 버튼이 실행이되고 값을 넘겨주는일을 하는것이다.
그 자체가 실행이 되야 this의 값은 그 부르는 객체가 될수 있지만
그저 값으로 넘겨주는 인자값으로 사용될떄는 그냥 그 api가 실행이될뿐이다.
마치 이코드는
btn.addEventListener('click', someone.who); === btn.addEventListener('click', mywho);
이렇게 볼수있다
var bindwho = mywho.bind(someone);
bindwho();
//여기서 this는 진짜 someone 이 나온다 왜? 바인드로 묶어주었기떄문이다.
this 의 값은 this를 사용하는 해당 함수를 어떻게 실행하느냐에 따라 바뀐다.
함수를 실행하는 방법엔 크게 4가지가 있습니다
(this를 이용하는) 해당함수를 이 4가지중 어떤 방식으로 실행하느냐에 따라 this의 값은 바뀝니다.
<함수 실행 방법 4가지>
1. foo(); 일반 함수 실행 방법(실행되는 부분을 찾아라) // window (참고로 스트릭트모드에서는 undefiend 나옴
예)
var age = 100;
function foo(){
var age = 99;
bar();
}
function bar(){
console.log(this.age); // 여기서 this는 윈도우를 가르킨다 왜?
}
foo();
왜냐면
일단 this.age를 실행시킨 함수를 찾아가보자
어디인가?
foo함수안에 bar() 여기서 실행이된다 근데
근데 문제는 일반함수 실행 하듯 실행했다 그래서 window로 되는거다.
<함수 실행 방법 4가지>
2. dot notation 방식 (점 방식)
ken.foo(); // 이런 방식임
예)
var age = 100;
var ken = {
age : 35,
foo : function foo (){
console.log(this.age);
}
};
ken.age();
여기서 this는 ken 객체를 가리킨다. (쩜 앞에있는 부분을 가르킨다)
또다른예)
var age = 100;
var ken = {
age : 25,
foo : function bar (){
console.log(this.age);
}
};
var wan = {
age : 31,
foo : ken.foo
};
var foo = ken.foo;
ken.foo(); // this값은 ken (dot notation 방식)
wan.foo(); // this 값은 wan (dot notation 방식)
foo(); // window (일반함수 방식)
====================
<함수 실행 방법 4가지>
3. 함수들이 같고있는 매소드들을 쓰는 방법 (function.prototype.call ,function.prototype.bind , function.prototype.apply)콜 , 바인드 , 어플리
*this는 기본적으로 window라고 했었죠. 몇 가지 방법으로 window를 다른 것으로 바꿀 수 있는데요. call, apply, bind에서 첫 번째 인자로 다른 것을 넣어주는 게 this를 바꾸는 방법 중 하나입니다.
*메소드들을 쓰는 예로, 함수의 arguments를 조작할 때 사용합니다. arguments는 함수라면 처음부터 갖고 있는 숨겨진 속성인데요. 바로 함수에 들어온 인자를 배열 형식으로(배열은 아닙니다. 유사 배열이라고 부릅니다.) 반환합니다.
*call 의 쓰임새는...일단 함수에서 arguments 를 반환하면 유사배열로 나오는데 진짜 배열이 아니므로 배열로바꿔주려면 join()을 써야되는데
그냥 쓰면 에러나서 Array.prototype.join.call(arguments) 이런식으로 쓰면 에러가 안나고 진짜 배열로 출력이되는거다 그래서
즉, call 을 왜쓰냐면 arguments를 배열로 만들떄 쓰는거다
*배열의 프로토타입에 있는 join 함수를 빌려 쓰는겁니다. this는 arguments를 가리키게 하고요. join 외에도 slice, concat 등등 모든 메소드를 이 방식으로 사용할 수 있습니다.
예)
var age = 100;
function foo(){
console.log(this.age);
}
var ken = {
age : 34
};
var bar = foo.bind(ken);
bar(); // 34
여기서 foo.bind(ken) 에서 함수가 바로 실행이되는게 아니고 bar에 담아줘서 bar()을 실행하게 해야 실행이된다.
<함수 실행 방법 4가지>
새로운거
새로운 객체가 생성되 생긴다
빈 객체가 새롭게 생기는거다 어디에도 this에도!
함수 실행 앞에 new 를 붙이면 그 함수는 빈객첵가 추가로 할당이되어 생긴다 this가 있으면 this에도 빈 객체가 할당이 된다.
빈 객체로 함수가 실행이 된다
예 1)
function foo(){
console.log(this);
}
new foo();
new 가 되면 실제로
new foo 함수 안에
this = {
};
이렇게 빈 객체가 생성이 되고
그다음
원래 foo함수 안에 있던 내용들이 새로운 foo함수에 할당이 된다
this = {
name : '바닐라코딩'
}
이런식으로 객체로 할당이 된다
그리고 이 함수에 자동적으로 리턴이 생기는 데 return this; 이렇게 이 함수를 리턴시킨다
정확히는
function (){
this.name = 'ken'
return this
이건 다른코드인데
이런식으로도 순서는 이렇게 된다
var Person = function (name) {
// 객체 리터럴로 새로운 객체를 생성한다.
// var this = {};
// 프로퍼티와 메서드를 추가한다.
this.name = name;
this.say = function () {
return 'I am ' + this.name;
};
// this를 반환한다.
// return this;
};
원래 say는 이렇게 되어진다
Person.prototype.say = function () { return 'I am ' + this.name; };
그리고
빈 객체가 아니라
// var this = Object.create(Person.prototype);
이렇게 생성된다
=============
function Person (name,age){
this.name = name;
this.age = age;
}
//called "instance"
var ken = new Person ('ken huh',34); //생성자함수
var wan = new Person ('wan huh',30);
console.log(ken);
console.log(wan);
============================